﻿using CKS2320.Common;
using CKS2320.Common.Model;
using CKS2320.Common.Utils;
using CKS2320.Controller;
using CKS2412.Controller.Common.Utils;
using CKS2412.Controller;
using MathNet.Numerics.Providers.SparseSolver;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging.Abstractions;
using Newtonsoft.Json;
using NPOI.POIFS.Crypt.Dsig;
using NPOI.SS.Formula.Functions;
using Org.BouncyCastle.Asn1.Ocsp;
using S7.Net;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using tscmcnet;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using System.Configuration;

namespace CKS2412.Controller.Action
{
    public class Op30Action_Service
    {
        #region 与主界面log日志方法绑定

        public delegate void AddLogHandler(string content, string source = "OP30");

        public static AddLogHandler AddLogEventHandler;
        #endregion 与主界面log日志方法绑定

        public delegate void AddDatanodeHandler(DataNode[] data);

        public AddDatanodeHandler AddDatanodeEventHandler;

        private SystemSettingModel sysModel = new SystemSettingModel();
        private int? lastTc_A = 0;//A通道最后一次执行任务
        private int? lastTc_B = 0;//B通道最后一次执行任务
        private SocketHelper socket;
        private ThicknessController _thicknessController;//膜厚控制器
        private bool _needConnectThicknessController;//需要连接膜厚传感器嘛？
        private int _controllerIndex;//控制器编号
        private int _localPort;//本地编号
        private string _dstIp;//目标IP
        private int _dstPort;//目标端口
        private LineLaserDeviceStatus _linelaserStatus;//线扫控制器状态
        private List<DataNode> _dataNodesRepository = new List<DataNode>();//存储膜厚总数据
        private DataNode[] _dataNodes;//存储膜厚临时数据
        private bool _thicknessResultA;//A件膜厚
        private bool _thicknessResultB;//B件膜厚
        private bool _lineLaserResult;
        private List<IndicatorToleranceZoneModel> _indicatorToleranceZoneModelList;
        private DateTime endData;
        private ParaShowSetModel paraInstance = new ParaShowSetModel();

        private KeyenceDataNew keyenceDataDetailList = new();

        //膜厚超时
        private int timeoutValue = Convert.ToInt32(ConfigurationManager.AppSettings["timediff_MH"].ToString());

        //膜厚算法
        private int arithmetic_MH = Convert.ToInt32(ConfigurationManager.AppSettings["arithmetic_MH"].ToString());

        private ArithmeticMH GetArithmeticModel(int model)
        {
            switch (model)
            {
                case 1:
                    return ArithmeticMH.Avg;

                case 2:
                    return ArithmeticMH.Min;

                default:
                    return ArithmeticMH.Min;
            }
        }

        /// <summary>
        /// 公差带
        /// </summary>
        public List<IndicatorToleranceZoneModel> IndicatorToleranceZoneModelList
        {
            get
            {
                return _indicatorToleranceZoneModelList;
            }
            private set
            {
                _indicatorToleranceZoneModelList = value;
            }
        }

        /// <summary>
        /// 线激光检测结果
        /// </summary>
        public bool LineLaserResult
        {
            get
            {
                return _lineLaserResult;
            }
        }

        /// <summary>
        /// A件膜厚检测结果
        /// </summary>
        public bool ThicknessResultA
        {
            get
            {
                return _thicknessResultA;
            }
        }

        /// <summary>
        /// B件膜厚检测结果
        /// </summary>
        public bool ThicknessResultB
        {
            get
            {
                return _thicknessResultB;
            }
        }

        public Op30Action_Service(int controllerIndex, int localPort, string dstIp, int dstPort, bool needConnectThicknessController = false)
        {
            _indicatorToleranceZoneModelList = IndicatortolerancezoneJsonLoad();
            paraInstance = GetParaShowSetModelConfig();//读取补偿配置
            this._needConnectThicknessController = needConnectThicknessController;
            if (_needConnectThicknessController)
            {
                _thicknessController = new ThicknessController(controllerIndex, localPort, dstIp, dstPort);
            }
            this._controllerIndex = controllerIndex;
            this._localPort = localPort;
            this._dstIp = dstIp;
            this._dstPort = dstPort;
            //AddDatanodeEventHandler += AddThicknessDataLog;
        }

        /// <summary>
        /// 读取配置文件
        /// </summary>
        /// <returns></returns>
        public List<IndicatorToleranceZoneModel> IndicatortolerancezoneJsonLoad()
        {
            string filePath = "Indicatortolerancezone.json";
            string text = File.ReadAllText(filePath);
            return JsonConvert.DeserializeObject<List<IndicatorToleranceZoneModel>>(text);
        }

        /// <summary>
        /// 读取配置文件
        /// </summary>
        /// <returns></returns>
        public ParaShowSetModel GetParaShowSetModelConfig()
        {
            string filePath = "ParaSet.json";
            string text = File.ReadAllText(filePath);
            return JsonConvert.DeserializeObject<ParaShowSetModel>(text);
        }

        //private void AddThicknessDataLog(DataNode[] data)
        //{
        //    using (StreamWriter writer = File.AppendText($@"Log\OP30Log\MH Data_{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.log"))
        //    {
        //        foreach (DataNode node in data)
        //        {
        //            //AddLogEventHandler?.Invoke();
        //            writer.WriteLine($"通道[{node.cfg.channel}]:{node.data.ToString("0.000")}");
        //        }

        //    }
        //}

        /// <summary>
        /// 解析通道
        /// </summary>
        /// <param name="channel">通道号</param>
        /// <param name="channelName">通道名称</param>
        /// <returns></returns>
        private string ParseChannel(int? channel, string channelName)
        {
            if (channel == 1)
            {
                if (channelName == "A")
                {
                    return "A1";
                }
                else if (channelName == "B")
                {
                    return "B1";
                }
            }
            if (channel == 2)
            {
                if (channelName == "A")
                {
                    return "A2";
                }
                else if (channelName == "B")
                {
                    return "B2";
                }
            }
            return "Empty Channel";
        }

        #region 获取线扫设备状态

        /// <summary>
        /// 获取线扫设备状态
        /// </summary>
        /// <param name="socket"></param>
        /// <returns></returns>
        private LineLaserDeviceStatus GetLineLaserDeviceState(SocketHelper socket, PLCController plc, string channelCode)
        {
            LineLaserDeviceStatus status = new LineLaserDeviceStatus();
            string devStr = socket.sharedSocketSend("DeviceStates,1\r\n");
            // Dev0,True;Dev1,False;Dev2,False;Dev3,False;\0D\0A
            string[] strSplit = devStr.Split(new char[] { ';', ',' });
            for (int i = 0; i < strSplit.Length; i++)
            {
                if (strSplit[i] == "Dev0")
                {
                    status.LineLaser1DeviceStatus = strSplit[i + 1] == "True" ? true : false;
                    plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.LineLaserDev1Ready, Convert.ToInt32(status.LineLaser1DeviceStatus));
                }
                if (strSplit[i] == "Dev1")
                {
                    status.LineLaser2DeviceStatus = strSplit[i + 1] == "True" ? true : false;
                    plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.LineLaserDev2Ready, Convert.ToInt32(status.LineLaser2DeviceStatus));
                }
                if (strSplit[i] == "Dev2")
                {
                    status.LineLaser3DeviceStatus = strSplit[i + 1] == "True" ? true : false;
                    plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.LineLaserDev3Ready, Convert.ToInt32(status.LineLaser3DeviceStatus));
                }
                if (strSplit[i] == "Dev3")
                {
                    status.LineLaser4DeviceStatus = strSplit[i + 1] == "True" ? true : false;
                    plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.LineLaserDev4Ready, Convert.ToInt32(status.LineLaser4DeviceStatus));
                }
            }
            //ReturnLineLaserDeviceState(plc, status);
            AddLogEventHandler?.Invoke($"{channelCode}通道已将所有线激光控制器结果传输至PLC");
            return status;
        }

        #endregion 获取线扫设备状态
        public static object _object = new object();

        //SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
        public async Task PlcRunOp30(PLCController plc, string channelCode, /*Socket*/SocketHelper socketHelper)
        {
            socket = socketHelper;

            string channelValue = "";
            _linelaserStatus = GetLineLaserDeviceState(socket, plc, channelCode);
            AddLogEventHandler?.Invoke($"OP30工站线扫控制器状态，控制器1：{_linelaserStatus.LineLaser1DeviceStatus.ToString()}，控制器2：{_linelaserStatus.LineLaser2DeviceStatus.ToString()}，控制器3：{_linelaserStatus.LineLaser3DeviceStatus.ToString()}，控制器4：{_linelaserStatus.LineLaser4DeviceStatus.ToString()}");
            if (_needConnectThicknessController)//需要实例才实例
            {
                bool res = _thicknessController.OpenConnection();
                //bool connRes = _thicknessController.SetConnectionOn(_controllerIndex);
                if (res /*&& connRes*/)
                {
                    //发送膜厚控制器准备状态
                    plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessReady, 1);
                }
                else
                {
                    //发送膜厚控制器准备状态
                    plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessReady, 2);
                }
                AddLogEventHandler?.Invoke($"膜厚状态已发送{res.ToString()}");
                _thicknessController.CloseConnection();
            }

            switch (channelCode.ToUpper())
            {
                case "A":
                    channelValue = "1";
                    break;

                case "B":
                    channelValue = "2";
                    break;
            }

            if (plc != null)
            {
                AddLogEventHandler?.Invoke($"OP30{channelCode}开启监听数据变化");


                while (true)
                {
                    try
                    {
                        if (plc.CheckConnect())
                            await Process(plc, channelCode, channelValue);
                    }
                    catch (Exception ex)
                    {
                        AddLogEventHandler?.Invoke("OP30未知异常：" + ex.Message);
                    }

                }
                // AddLogEventHandler?.Invoke("连接断开，监听结束");
                //bool closeResult = _thicknessController.CloseConnection();
                //if (closeResult)
                //{
                //    AddLogEventHandler?.Invoke("膜厚控制器断开连接");
                //}
            }
            else
            {
            }
        }


        int? lastTc_3d = 0;//3d启动最后一次任务号
        int? lastTc_Thickness = 0;//膜厚启动 最后一次任务号
        int? lastTc_upload = 0;//上传信号最后一次任务号
        int? startUpload = 0;



        private async Task Process(PLCController plc, string channelCode, string channelValue)
        {
            try
            {



                //await _semaphore.WaitAsync();
                //KeyenceDataNew keyenceDataDetailList = new();
                string offsetStr = SignalAdrSetting.HardwareStart;//3D控制器启动
                string mhStr = SignalAdrSetting.ThicknessStart;//膜厚启动

                //收到plc触发信号后 触发3D
                int? start3D_Thickness = plc?.ReadIntOne(SignalAdrSetting.dbOp30, Convert.ToInt32(offsetStr));//收到启动3D和膜厚信号
                int? channel_topc = plc?.ReadIntOne(SignalAdrSetting.dbOp30, Convert.ToInt32(SignalAdrSetting.ChannelCode_OP30));//读取通道号
                int? start_Thickness = plc?.ReadIntOne(SignalAdrSetting.dbOp30, Convert.ToInt32(mhStr));
                if (start3D_Thickness == 1 && start3D_Thickness != lastTc_3d /*|| start3D_Thickness == 2*/)
                {
                    keyenceDataDetailList = new();
                    await ReturnLineLaserResult(plc, channelCode, 0);
                    if (channelCode == "A")
                    {
                        plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessResultA, 0);
                    }
                    else if (channelCode == "B")
                    {
                        plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessResultB, 0);
                    }

                    //给3D发送获取设备状态报文
                    AddLogEventHandler?.Invoke(ParseChannel(channel_topc, channelCode) + "件收到PLC的点激光开启信号");
                    //收到报文后反馈给plc
                    GetLineLaserDeviceState(socket, plc, channelCode);
                    string triggerStr = socket.sharedSocketSend($"Trigger,{channelValue}\r\n");//触发几通道
                    AddLogEventHandler?.Invoke(channelCode + "件收到PLC的点激光开启信号");
                    AddLogEventHandler?.Invoke(channelCode + $"件线激光开启信号发送：Trigger,{channelValue}\r\n");
                    //告诉plc已经开始工作
                    plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.StartAck, 1);
                    AddLogEventHandler?.Invoke(channelCode + "通道告诉plc开始工作");

                    AddLogEventHandler?.Invoke(channelCode + "件线激光开启接收消息：" + triggerStr);
                    if (!triggerStr.Contains("OK"))//说明通讯失败了
                    {
                        await ReturnLineLaserResult(plc, channelCode, 2);
                    }

                    if (_needConnectThicknessController)//需要实例才实例
                    {
                        bool res = _thicknessController.OpenConnection();
                        bool connres = _thicknessController.SetConnectionOn(_controllerIndex);
                        _dataNodesRepository = new List<DataNode>();//初始化
                                                                    //Task.Factory.StartNew(() =>
                                                                    //{
                        #region 新逻辑
                        //lock (_object)
                        //{
                        //while (true/*start3D_Thickness == 1*/)
                        //{
                        //    short? start3d = plc?.ReadIntOne(SignalAdrSetting.dbOp30, Convert.ToInt32(offsetStr));
                        //    start_Thickness = plc?.ReadIntOne(SignalAdrSetting.dbOp30, Convert.ToInt32(mhStr));

                        // if (start_Thickness == 1 && start_Thickness !=
                        // lastTc_Thickness)//采集 { AddLogEventHandler?.Invoke(channelCode +
                        // "件膜厚控制器建立连接"); ERRCODE err =
                        // _thicknessController.SetDataOutputOn(_controllerIndex); if (err
                        // == ERRCODE.OK) { AddLogEventHandler?.Invoke(channelCode +
                        // "件膜厚数据开始采集正常"); plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc,
                        // SignalAdrSetting.ThicknessReady, 1); } else { //发送膜厚控制器准备状态
                        // plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc,
                        // SignalAdrSetting.ThicknessReady, 2);
                        // AddLogEventHandler?.Invoke(channelCode + "件膜厚数据开始采集异常");
                        // _thicknessController.CloseConnection(); } lastTc_Thickness =
                        // start_Thickness; } else if (start_Thickness == 2 &&
                        // start_Thickness != lastTc_Thickness)//停止采集 { Task.Delay(20);
                        // _dataNodes = new DataNode[] { }; ERRCODE errTransfer =
                        // _thicknessController.TransferAllDataNode(ref _dataNodes,
                        // 2000000); if (errTransfer == ERRCODE.OK) { if (_dataNodes.Length
                        // > 0) { AddLogEventHandler?.Invoke(channelCode +
                        // "件膜厚数据传输正常，且数组有值"); } else {
                        // AddLogEventHandler?.Invoke(channelCode + "件膜厚数据传输异常，数组无值"); }
                        // ERRCODE err = _thicknessController.SetDataOutputOff(_controllerIndex);

                        // if (err == ERRCODE.OK)//膜厚正常 { //List<DataNode> tmpListDataNode =
                        // _dataNodes.ToList(); //for (int i = 0; i < 130; i++) //{ //
                        // DataNode dn4dis = new DataNode(); // dn4dis.cfg.channel = 4; //
                        // dn4dis.data = -2147.483648; // tmpListDataNode.Add(dn4dis); //
                        // DataNode dn4th = new DataNode(); // dn4th.cfg.channel = 4; //
                        // dn4th.data = -2147.483648; // tmpListDataNode.Add(dn4th); //
                        // DataNode dn3dis = new DataNode(); // dn3dis.cfg.channel = 3; //
                        // dn3dis.data = -2147.483648; // tmpListDataNode.Add(dn3dis); //
                        // DataNode dn3th = new DataNode(); // dn3th.cfg.channel = 3; //
                        // dn3th.data = -2147.483648; // tmpListDataNode.Add(dn3th); //
                        // DataNode dn2dis = new DataNode(); // dn2dis.cfg.channel = 2; //
                        // dn2dis.data = -2147.483648; // tmpListDataNode.Add(dn2dis); //
                        // DataNode dn2th = new DataNode(); // dn2th.cfg.channel = 2; //
                        // dn2th.data = -2147.483648; // tmpListDataNode.Add(dn2th); //
                        // DataNode dn1dis = new DataNode(); // dn1dis.cfg.channel = 1; //
                        // dn1dis.data = -2147.483648; // tmpListDataNode.Add(dn1dis); //
                        // DataNode dn1th = new DataNode(); // dn1th.cfg.channel = 1; //
                        // dn1th.data = -2147.483648; // tmpListDataNode.Add(dn1th); //}
                        // //_dataNodes = tmpListDataNode.ToArray();
                        // _dataNodesRepository.AddRange(_dataNodes);
                        // plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc,
                        // SignalAdrSetting.ThicknessReady, 1);
                        // AddLogEventHandler?.Invoke(channelCode + "件膜厚数据停止采集正常"); } else
                        // if (err == ERRCODE.DEVICE_NOT_CONNECTED) {
                        // AddLogEventHandler?.Invoke(channelCode + "件膜厚数据停止采集异常，设备未连接");
                        // plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc,
                        // SignalAdrSetting.ThicknessReady, 2);
                        // _thicknessController.CloseConnection();
                        // _thicknessController.OpenConnection();
                        // _thicknessController.SetConnectionOn(_controllerIndex); } else if
                        // (err == ERRCODE.CMD_FAILED) {
                        // AddLogEventHandler?.Invoke(channelCode + "件膜厚数据停止采集异常，设备没有回复");
                        // plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc,
                        // SignalAdrSetting.ThicknessReady, 2);
                        // _thicknessController.CloseConnection();
                        // _thicknessController.OpenConnection();
                        // _thicknessController.SetConnectionOn(_controllerIndex); } else {
                        // AddLogEventHandler?.Invoke(channelCode + $"件膜厚数据停止采集异常
                        // {err.ToString()}"); plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc,
                        // SignalAdrSetting.ThicknessReady, 2);
                        // _thicknessController.CloseConnection();
                        // _thicknessController.OpenConnection();
                        // _thicknessController.SetConnectionOn(_controllerIndex); }
                        // Task.Delay(20); } else { AddLogEventHandler?.Invoke(channelCode +
                        // "件膜厚数据传输异常1");
                        // _thicknessController.SetDataOutputOff(_controllerIndex);
                        // plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc,
                        // SignalAdrSetting.ThicknessReady, 2);
                        // _thicknessController.CloseConnection();
                        // _thicknessController.OpenConnection();
                        // _thicknessController.SetConnectionOn(_controllerIndex);
                        // AddLogEventHandler?.Invoke(channelCode + "膜厚控制器关闭连接5"); }

                        // lastTc_Thickness = start_Thickness; } else if (start_Thickness ==
                        // 0) { lastTc_Thickness = start_Thickness; }

                        //    if (start3d == 2 || start3d == 0)
                        //    {
                        //        break;
                        //    }
                        //}
                        //}

                        // lastTc_Thickness = start_Thickness; } else if (start_Thickness ==
                        // 0) { lastTc_Thickness = start_Thickness; }

                        //    if (start3d == 2 || start3d == 0)
                        //    {
                        //        break;
                        //    }
                        //}
                        //});
                        #endregion 新逻辑

                        #region
                        ////_thicknessController = new ThicknessController(_controllerIndex, _localPort, _dstIp, _dstPort);
                        //AddLogEventHandler?.Invoke(channelCode + "件收到PLC的膜厚开启信号");
                        ////await Task.Delay(500);
                        //bool openResult = _thicknessController.OpenConnection();
                        //if (openResult)
                        //{
                        //    AddLogEventHandler?.Invoke(channelCode + "件膜厚控制器开始连接");
                        //    await Task.Delay(100);
                        //    bool connResult = _thicknessController.SetConnectionOn(_controllerIndex);
                        //    if (connResult)
                        //    {
                        //        //发送膜厚控制器准备状态
                        //        plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessReady, 1);
                        //        stData = DateTime.Now;
                        //        AddLogEventHandler?.Invoke(channelCode + "件膜厚控制器建立连接");
                        //        ERRCODE err = _thicknessController.SetDataOutputOn(_controllerIndex);
                        //        if (err == ERRCODE.OK)
                        //        {
                        //            AddLogEventHandler?.Invoke(channelCode + "件膜厚数据开始采集正常");
                        //            //plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessWorkA, 1);
                        //            plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessReady, 1/*2*/);
                        //        }
                        //        else
                        //        {
                        //            //发送膜厚控制器准备状态
                        //            plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessReady, 1);
                        //            _thicknessController.CloseConnection();
                        //            AddLogEventHandler?.Invoke(channelCode + "件膜厚数据开始采集异常");
                        //            //AddLogEventHandler?.Invoke(channelCode + "膜厚控制器关闭连接1");
                        //        }
                        //    }
                        //    else
                        //    {
                        //        plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessReady, 1/*2*/);
                        //        _thicknessController.CloseConnection();
                        //        AddLogEventHandler?.Invoke(channelCode + "件膜厚控制器建立连接异常");
                        //        //AddLogEventHandler?.Invoke(channelCode + "膜厚控制器关闭连接2");
                        //    }
                        //}
                        //else
                        //{
                        //    bool closeResult = _thicknessController.CloseConnection();
                        //    if (closeResult)
                        //    {
                        //        AddLogEventHandler?.Invoke(channelCode + "件膜厚控制器关闭连接正常");
                        //    }
                        //    else
                        //    {
                        //        AddLogEventHandler?.Invoke(channelCode + "件膜厚控制器关闭连接异常");
                        //    }
                        //    plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessReady, 1/*2*/);
                        //    AddLogEventHandler?.Invoke(channelCode + "件膜厚控制器连接异常");
                        //}
                        #endregion
                    }

                    //AddLogEventHandler?.Invoke(channelCode + "件线激光开启接收消息：" + triggerStr);
                    //if (!triggerStr.Contains("OK"))//说明通讯失败了
                    //{
                    //    await ReturnLineLaserResult(plc, channelCode, 2);
                    //}

                    lastTc_3d = start3D_Thickness;
                }
                if (_needConnectThicknessController)
                {
                    if (start_Thickness == 1 && start_Thickness != lastTc_Thickness)//采集
                    {
                        AddLogEventHandler?.Invoke(channelCode + "件膜厚控制器建立连接");
                        ERRCODE err = _thicknessController.SetDataOutputOn(_controllerIndex);
                        if (err == ERRCODE.OK)
                        {
                            AddLogEventHandler?.Invoke(channelCode + "件膜厚数据开始采集正常");
                            plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.MhControlFeedback, 1);//膜厚开始正常
                            plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessReady, 1);
                        }
                        else
                        {
                            plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.MhControlFeedback, 2);//膜厚开始异常
                                                                                                                 //发送膜厚控制器准备状态
                                                                                                                 //plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessReady, 2);
                            AddLogEventHandler?.Invoke(channelCode + "件膜厚数据开始采集异常");
                            _thicknessController.CloseConnection();
                            _thicknessController.OpenConnection();
                            _thicknessController.SetConnectionOn(_controllerIndex);
                        }
                        lastTc_Thickness = start_Thickness;
                    }
                    else if (start_Thickness == 2 && start_Thickness != lastTc_Thickness)//停止采集
                    {
                        //await Task.Delay(20);
                        _dataNodes = new DataNode[] { };
                        ERRCODE errTransfer = _thicknessController.TransferAllDataNode(ref _dataNodes, 2000000);
                        AddLogEventHandler?.Invoke($"膜厚出现异常：{errTransfer.ToString()}");
                        if (errTransfer == ERRCODE.OK)
                        {
                            if (_dataNodes.Length > 0)
                            {
                                AddLogEventHandler?.Invoke(channelCode + "件膜厚数据传输正常，且数组有值");
                            }
                            else
                            {
                                AddLogEventHandler?.Invoke(channelCode + "件膜厚数据传输异常，数组无值");
                            }
                            ERRCODE err = _thicknessController.SetDataOutputOff(_controllerIndex);

                            if (err == ERRCODE.OK)//膜厚正常
                            {
                                //List<DataNode> tmpListDataNode = _dataNodes.ToList();
                                //for (int i = 0; i < 130; i++)
                                //{
                                //    DataNode dn4dis = new DataNode();
                                //    dn4dis.cfg.channel = 4;
                                //    dn4dis.data = -2147.483648;
                                //    tmpListDataNode.Add(dn4dis);
                                //    DataNode dn4th = new DataNode();
                                //    dn4th.cfg.channel = 4;
                                //    dn4th.data = -2147.483648;
                                //    tmpListDataNode.Add(dn4th);
                                //    DataNode dn3dis = new DataNode();
                                //    dn3dis.cfg.channel = 3;
                                //    dn3dis.data = -2147.483648;
                                //    tmpListDataNode.Add(dn3dis);
                                //    DataNode dn3th = new DataNode();
                                //    dn3th.cfg.channel = 3;
                                //    dn3th.data = -2147.483648;
                                //    tmpListDataNode.Add(dn3th);
                                //    DataNode dn2dis = new DataNode();
                                //    dn2dis.cfg.channel = 2;
                                //    dn2dis.data = -2147.483648;
                                //    tmpListDataNode.Add(dn2dis);
                                //    DataNode dn2th = new DataNode();
                                //    dn2th.cfg.channel = 2;
                                //    dn2th.data = -2147.483648;
                                //    tmpListDataNode.Add(dn2th);
                                //    DataNode dn1dis = new DataNode();
                                //    dn1dis.cfg.channel = 1;
                                //    dn1dis.data = -2147.483648;
                                //    tmpListDataNode.Add(dn1dis);
                                //    DataNode dn1th = new DataNode();
                                //    dn1th.cfg.channel = 1;
                                //    dn1th.data = -2147.483648;
                                //    tmpListDataNode.Add(dn1th);
                                //}
                                //_dataNodes = tmpListDataNode.ToArray();
                                _dataNodesRepository.AddRange(_dataNodes);
                                plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessReady, 1);
                                AddLogEventHandler?.Invoke(channelCode + "件膜厚数据停止采集正常");
                            }
                            else if (err == ERRCODE.DEVICE_NOT_CONNECTED)
                            {
                                AddLogEventHandler?.Invoke(channelCode + "件膜厚数据停止采集异常，设备未连接");
                                //plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessReady, 2);
                                _thicknessController.CloseConnection();
                                _thicknessController.OpenConnection();
                                _thicknessController.SetConnectionOn(_controllerIndex);
                            }
                            else if (err == ERRCODE.CMD_FAILED)
                            {
                                AddLogEventHandler?.Invoke(channelCode + "件膜厚数据停止采集异常，设备没有回复");
                                //plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessReady, 2);
                                _thicknessController.CloseConnection();
                                _thicknessController.OpenConnection();
                                _thicknessController.SetConnectionOn(_controllerIndex);
                            }
                            else
                            {
                                AddLogEventHandler?.Invoke(channelCode + $"件膜厚数据停止采集异常 {err.ToString()}");
                                //plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessReady, 2);
                                _thicknessController.CloseConnection();
                                _thicknessController.OpenConnection();
                                _thicknessController.SetConnectionOn(_controllerIndex);
                            }
                            //await Task.Delay(20);
                        }
                        else
                        {
                            AddLogEventHandler?.Invoke(channelCode + "件膜厚数据传输异常1");
                            _thicknessController.SetDataOutputOff(_controllerIndex);
                            //plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessReady, 2);
                            _thicknessController.CloseConnection();
                            _thicknessController.OpenConnection();
                            _thicknessController.SetConnectionOn(_controllerIndex);
                            AddLogEventHandler?.Invoke(channelCode + "膜厚控制器关闭连接5");
                        }
                        plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.MhControlFeedback, 0);//关闭膜厚控制信号
                        lastTc_Thickness = start_Thickness;
                    }
                    else if (start_Thickness == 0)
                    {
                        lastTc_Thickness = start_Thickness;
                    }
                }

                /*else*/
                if (start3D_Thickness == 2 && start3D_Thickness != lastTc_3d)//收到停止信号
                {
                    DateTime dt3DStart = DateTime.Now;
                    DateTime dt3DEnd = new DateTime();

                    //告诉plc已经开始工作
                    plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.StartAck, 1);
                    AddLogEventHandler?.Invoke(channelCode + "通道告诉plc开始工作-STOP分支");
                    AddLogEventHandler?.Invoke(channelCode + "件收到PLC的线激光停止信号");
                    AddLogEventHandler?.Invoke(channelCode + "件收到PLC的膜厚停止信号");
                    AddLogEventHandler?.Invoke(channelCode + $"件线激光停止信号发送：Stop,{channelValue}\r\n");
                    string stopStr = socket.sharedSocketSend($"Stop,{channelValue}\r\n");
                    AddLogEventHandler?.Invoke(channelCode + $"件膜厚控制器发送停止信号");
                    //需要才去判断膜厚
                    if (_needConnectThicknessController)
                    {
                        //await Task.Delay(20);
                        ///*ERRCODE*/
                        ////_dataNodes = new DataNode[300000];//声明5000个长度的数据
                        //_dataNodes = new DataNode[] { };
                        //ERRCODE errTransfer = _thicknessController.TransferAllDataNode(ref _dataNodes, 2000000);
                        //if (errTransfer == ERRCODE.OK)
                        //{
                        //    if (_dataNodes.Length > 0)
                        //    {
                        //        AddLogEventHandler?.Invoke(channelCode + "件膜厚数据传输正常，且数组有值");
                        //    }
                        //    else
                        //    {
                        //        AddLogEventHandler?.Invoke(channelCode + "件膜厚数据传输异常，数组无值");
                        //    }
                        //    ERRCODE err = _thicknessController.SetDataOutputOff(_controllerIndex/*, ref _dataNodes*/);
                        //    endData = DateTime.Now;
                        //    AddLogEventHandler?.Invoke($"采集间隔{(endData - stData).TotalMilliseconds}毫秒");
                        //    if (err == ERRCODE.OK)//膜厚正常
                        //    {
                        //        plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessReady, 1);
                        //        AddLogEventHandler?.Invoke(channelCode + "件膜厚数据停止采集正常");
                        //    }
                        //    else if (err == ERRCODE.DEVICE_NOT_CONNECTED)
                        //    {
                        //        AddLogEventHandler?.Invoke(channelCode + "件膜厚数据停止采集异常，设备未连接");
                        //        plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessReady, 1/* 2*/);
                        //        _thicknessController.CloseConnection();
                        //        //AddLogEventHandler?.Invoke(channelCode + "膜厚控制器关闭连接3");
                        //    }
                        //    else if (err == ERRCODE.CMD_FAILED)
                        //    {
                        //        AddLogEventHandler?.Invoke(channelCode + "件膜厚数据停止采集异常，设备没有回复");
                        //        plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessReady, 1/* 2*/);
                        //        _thicknessController.CloseConnection();
                        //    }
                        //    else
                        //    {
                        //        AddLogEventHandler?.Invoke(channelCode + $"件膜厚数据停止采集异常 {err.ToString()}");
                        //        plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessReady, 1/* 2*/);
                        //        _thicknessController.CloseConnection();
                        //        //AddLogEventHandler?.Invoke(channelCode + "膜厚控制器关闭连接4");
                        //    }
                        //    await Task.Delay(20);
                        //    //关闭膜厚连接
                        //    bool closeResult = _thicknessController.CloseConnection();
                        //    ////DisplayThicknessData(_dataNodes);
                        //    AddDatanodeEventHandler?.Invoke(_dataNodes);
                        //    if (closeResult)
                        //    {
                        //        AddLogEventHandler?.Invoke(channelCode + "件膜厚控制器关闭连接正常");
                        //    }
                        //    else
                        //    {
                        //        AddLogEventHandler?.Invoke(channelCode + "件膜厚控制器关闭连接异常");
                        //    }
                        //}
                        //else
                        //{
                        //    AddLogEventHandler?.Invoke(channelCode + "件膜厚数据传输异常1");
                        //    _thicknessController.SetDataOutputOff(_controllerIndex/*, ref _dataNodes*/);
                        //    plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessReady, 1/* 2*/);
                        //    _thicknessController.CloseConnection();
                        //    AddLogEventHandler?.Invoke(channelCode + "膜厚控制器关闭连接5");
                        //}

                        bool recordFlag = ConfigurationManager.AppSettings["recordFlag"].ToString().ToLower() == "true" ? true : false;
                        if (recordFlag)
                        {
                            await RecordThicknessRealData(ParseChannel(channel_topc, channelCode),/*_dataNodes*/_dataNodesRepository.ToArray());
                        }
                        if (channelCode == "A")
                        {
                            _thicknessResultA = await ThicknessGetDataAndJudgement(plc, _dataNodesRepository.ToArray()/*_dataNodes*/, _indicatorToleranceZoneModelList, "A");
                            DataShift.ThicknessAResult = _thicknessResultA;//存放结果
                            if (_thicknessResultA)
                            {
                                AddLogEventHandler?.Invoke("A" + "件膜厚公差带判断OK");
                            }
                            else
                            {
                                AddLogEventHandler?.Invoke("A" + "件膜厚公差带判断NG");
                            }
                            _thicknessResultB = await ThicknessGetDataAndJudgement(plc, _dataNodesRepository.ToArray()/*_dataNodes*/, _indicatorToleranceZoneModelList, "B");
                            DataShift.ThicknessBResult = _thicknessResultB;
                            if (_thicknessResultB)
                            {
                                AddLogEventHandler?.Invoke("B" + "件膜厚公差带判断OK");
                            }
                            else
                            {
                                AddLogEventHandler?.Invoke("B" + "件膜厚公差带判断NG");
                            }
                        }
                    }

                    AddLogEventHandler?.Invoke(channelCode + "件线激光停止信号接收消息：" + stopStr);
                    if (stopStr == "error")//线激光掉线
                    {
                        await ReturnLineLaserResult(plc, channelCode, 2);
                    }
                    else
                    {
                        //ReturnLineLaserResult(plc, channelCode, 0);
                    }

                    //获取线激光数据并判断值是否合格
                    keyenceDataDetailList = await LineLaserGetDataAndJudgement(plc, _indicatorToleranceZoneModelList, channelCode, channelValue)/*.Result*/;
                    dt3DEnd = DateTime.Now;
                    double dt3Dtotal = (dt3DEnd - dt3DStart).TotalSeconds;
                    AddLogEventHandler?.Invoke(channelCode + "件收到停止信号后运行时间：" + dt3Dtotal);
                    lastTc_3d = start3D_Thickness;
                    //GC.Collect();
                }
                /*else*/
                if (start3D_Thickness == 0)
                {
                    //if (start3D_Thickness == 0 && start3D_Thickness != lastTc_3d)
                    //{
                    //告诉plc已经停止工作
                    plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.StartAck, 0);
                    await Task.Delay(100);
                    //AddLogEventHandler?.Invoke(channelCode + "通道告诉plc停止工作");
                    //ReturnLineLaserResult(plc, channelCode, 0);
                    //plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessResultA, 0);
                    //plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessResultB, 0);
                    //AddLogEventHandler?.Invoke(channelCode + "件清除数据完毕");
                    //}
                    lastTc_3d = start3D_Thickness;
                }

                DateTime startTime = DateTime.Now;
                TimeSpan timeLimit = TimeSpan.FromSeconds(30);

                //读取上传信号
                startUpload = plc?.ReadIntOne(SignalAdrSetting.dbOp30, Convert.ToInt32(SignalAdrSetting.UploadStart_OP30));
                //int? status = 0;
                string adr = "";
                //switch (channelCode)
                //{
                //    case "A":
                //        status = plc?.ReadIntOne(SignalAdrSetting.dbOp30, Convert.ToInt32(SignalAdrSetting.ProductStatusA_OP30));
                //        break;
                //    case "B":
                //        status = plc?.ReadIntOne(SignalAdrSetting.dbOp30, Convert.ToInt32(SignalAdrSetting.ProductStatusB_OP30));
                //        break;
                //}
                switch (channelCode)
                {
                    case "A":
                        adr = SignalAdrSetting.ProductStatusA_OP30;
                        break;

                    case "B":
                        adr = SignalAdrSetting.ProductStatusB_OP30;
                        break;
                }

                if (startUpload == 1 && startUpload != lastTc_upload)
                {
                    await Task.Delay(100);
                    int? status = plc?.ReadIntOne(SignalAdrSetting.dbOp30, Convert.ToInt32(adr));
                    AddLogEventHandler?.Invoke(channelCode + $"件收到PLC的状态信号:{status}");
                    lastTc_upload = startUpload;
                    if (status == 1)
                    {
                        AddLogEventHandler?.Invoke(channelCode + "件收到PLC的上传信号");
                        try
                        {
                            await PlcUploadDataAndSaveData(plc, channelCode, channel_topc, keyenceDataDetailList, _indicatorToleranceZoneModelList);
                        }
                        catch (Exception ex)
                        {
                            if (channelCode == "A")
                            {
                                //发生上传错误信号
                                plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.UploadDoneA_OP30, 2);
                            }
                            else //B
                            {
                                plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.UploadDoneB_OP30, 2);
                            }
                            AddLogEventHandler?.Invoke("发生错误：" + ex.Message);
                        }
                        AddLogEventHandler?.Invoke(channelCode + "件PLC的上传信号已复位");
                    }
                    //lastTc_upload = startUpload;
                }
                else if (startUpload == 0)
                {
                    if (channelCode == "A")
                    {
                        plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.UploadDoneA_OP30, 0);
                    }
                    else
                    {
                        plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.UploadDoneB_OP30, 0);
                    }
                    await Task.Delay(200);
                    lastTc_upload = 0;
                }
            }
            catch (Exception ex)
            {
                AddLogEventHandler?.Invoke("发生错误：" + ex.Message);
            }

        }

        /// <summary>
        /// 写入膜厚真实数据至csv
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private async Task RecordThicknessRealData(/*DataNode[] data*/string channel, List<double> listDst, List<double> listData)
        {
            //string fileName = $@"D:\Data\{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.csv";
            string fileName = $@"Data\{DateTime.Now.ToString("yyyyMMddHHmmssfff")}_{channel}.csv";
            try
            {
                DataTable DT = new DataTable();
                DT.Columns.Add("Channel", typeof(string));
                DT.Columns.Add("Distance", typeof(string));
                DT.Columns.Add("Data", typeof(string));
                if (listDst.Any() && listData.Any())
                {
                    for (int i = 0; i < listDst.Count; i++)
                    {
                        DT.Rows.Add(new object[] { channel, listDst[i].ToString(), listData[i].ToString() });
                    }
                }
                else
                {
                    DT.Rows.Add(new object[] { "ERROR", "9999" });
                }
                CSVHelper.WriteCSV(fileName, DT);
                AddLogEventHandler?.Invoke($"记录膜厚真实数据成功，文件名{fileName}");
            }
            catch (Exception ex)
            {
                AddLogEventHandler?.Invoke($"记录膜厚真实数据失败，文件名{fileName},错误原因{ex.Message}");
            }
        }

        /// <summary>
        /// 写入膜厚真实数据至csv
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private async Task RecordThicknessRealData(string channel, DataNode[] data)
        {
            //string fileName = $@"D:\Data\{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.csv";
            string fileName = $@"Data\{channel}_{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.csv";
            try
            {
                DataTable DT = new DataTable();
                DT.Columns.Add("Channel", typeof(string));
                DT.Columns.Add("Data", typeof(string));
                if (data.Length > 0)
                {
                    for (int i = 0; i < data.Length; i++)
                    {
                        DT.Rows.Add(new object[] { data[i].cfg.channel.ToString(), data[i].data.ToString() });
                    }
                }
                else
                {
                    DT.Rows.Add(new object[] { "ERROR", "9999" });
                }
                CSVHelper.WriteCSV(fileName, DT);
                AddLogEventHandler?.Invoke($"记录膜厚真实数据成功，文件名{fileName}");
            }
            catch
            {
                AddLogEventHandler?.Invoke($"记录膜厚真实数据失败，文件名{fileName}");
            }
        }

        private async Task DisplayThicknessData(DataNode[] data)
        {
            try
            {
                AddLogEventHandler?.Invoke("膜厚数据获取");
                if (data != null && data.Length > 0)
                {
                    foreach (DataNode node in data)
                    {
                        AddLogEventHandler?.Invoke($"通道[{node.cfg.channel}]:{node.data.ToString("0.000")}");
                    }
                }
                else
                {
                    AddLogEventHandler?.Invoke("膜厚数据获取为空");
                }
            }
            catch (Exception ex)
            {
                AddLogEventHandler?.Invoke("膜厚数据获取异常 进入catch");
            }
        }

        /// <summary>
        /// 更新上传数据并保存数据
        /// </summary>
        /// <param name="plc">plc对象</param>
        /// <param name="channelCode">通道代号</param>
        /// <param name="lineLaserDataDetailList">线激光数据详情</param>
        /// <returns></returns>
        private async Task PlcUploadDataAndSaveData(PLCController plc, string channelCode, int? channel_topc, KeyenceDataNew lineLaserDataDetailList, List<IndicatorToleranceZoneModel> indicatorToleranceZoneList)
        {
            AddLogEventHandler?.Invoke(channelCode + "件开始读取PLC数据");
            var uploadResult = await PlcUploadData(plc, channelCode, channel_topc);
            if (uploadResult != null && uploadResult.Code == 1)
            {
                AddLogEventHandler?.Invoke(channelCode + "件开始数据解析");
                var dataSaveResult = SaveData(uploadResult.Data, channelCode, channel_topc, lineLaserDataDetailList, indicatorToleranceZoneList);
                if (dataSaveResult != null && dataSaveResult?.Code == 1)
                {
                    if (channelCode == "A")
                    {
                        plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.UploadDoneA_OP30, 1);
                        AddLogEventHandler?.Invoke("A写入数据：" + 1);
                    }
                    else
                    {
                        plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.UploadDoneB_OP30, 1);
                        AddLogEventHandler?.Invoke("B写入数据：" + 1);
                    }
                    AddLogEventHandler?.Invoke(channelCode + "件本次数据读取已完成");
                }
                else
                {
                    if (channelCode == "A")
                    {
                        plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.UploadDoneA_OP30, 2);
                    }
                    else
                    {
                        plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.UploadDoneB_OP30, 2);
                    }
                    AddLogEventHandler?.Invoke("数据保存失败 " + dataSaveResult?.Message);
                }
            }
            else
            {
                if (channelCode == "A")
                {
                    plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.UploadDoneA_OP30, 2);
                }
                else
                {
                    plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.UploadDoneB_OP30, 2);
                }
                AddLogEventHandler?.Invoke("数据保存失败，数据异常，内容不存在值");
            }
        }

        /// <summary>
        /// 保存数据
        /// </summary>
        /// <param name="data">数据</param>
        /// <param name="channelCode">通道代号</param>
        /// <param name="lineLaserDataDetailList">线激光数据</param>
        /// <param name="indicatorToleranceZoneList">公差带配置</param>
        /// <returns></returns>
        private ResultReturn SaveData(dynamic data, string channelCode, int? channel_topc, KeyenceDataNew lineLaserDataDetailList, List<IndicatorToleranceZoneModel> indicatorToleranceZoneList)
        {
            try
            {
                //string request = JsonConvert.SerializeObject(data);
                //string response = GetApiUtils.GetPostApi(request, sysModel.webApiUrl + "api/ThicknessDetection/Add").GetAwaiter().GetResult();
                //ResultReturn result = JsonConvert.DeserializeObject<ResultReturn>(response);
                //if (result != null && result.Code == 1 /*&& lineLaserDataDetailList != null*/ && lineLaserDataDetailList.circleDiameter != null /*&& lineLaserDataDetailList.circleDiameter.Any()*/)
                //{
                //    AddLogEventHandler?.Invoke(channelCode + "件线激光数据保存");
                //    LineLaserDataSave(lineLaserDataDetailList, channelCode, Guid.Parse(result.Data), indicatorToleranceZoneList);
                //}
                //return result;
                string request = JsonConvert.SerializeObject(data);
                ThicknessDetectionModel thicknessDetectionModel = data;
                List<DetectionDetail> list = new List<DetectionDetail>();
                if (lineLaserDataDetailList.circleDiameter.Any())
                {
                    AddLogEventHandler?.Invoke(channelCode + "件线激光数据保存");
                    list = LineLaserDataSave(lineLaserDataDetailList, channelCode, channel_topc, thicknessDetectionModel.PartCode/*Guid.Parse(result.Data)*/, indicatorToleranceZoneList).Result;
                    thicknessDetectionModel.FrontThicknessResult1 = list.Find(f => f.DetectedType == "FCT1")?.DetectedStatus == 1 ? true : false;
                    thicknessDetectionModel.FrontThicknessResult2 = list.Find(f => f.DetectedType == "FCT2")?.DetectedStatus == 1 ? true : false;
                    thicknessDetectionModel.FrontThicknessResult3 = list.Find(f => f.DetectedType == "FCT3")?.DetectedStatus == 1 ? true : false;
                    thicknessDetectionModel.FrontThicknessResult4 = list.Find(f => f.DetectedType == "FCT4")?.DetectedStatus == 1 ? true : false;
                    thicknessDetectionModel.FrontThicknessResult5 = list.Find(f => f.DetectedType == "FCT5")?.DetectedStatus == 1 ? true : false;
                    thicknessDetectionModel.FrontThicknessResult6 = list.Find(f => f.DetectedType == "FCT6")?.DetectedStatus == 1 ? true : false;
                    thicknessDetectionModel.FrontThicknessResult7 = list.Find(f => f.DetectedType == "FCT7")?.DetectedStatus == 1 ? true : false;
                    thicknessDetectionModel.BackThicknessResult1 = list.Find(f => f.DetectedType == "BCT1")?.DetectedStatus == 1 ? true : false;
                    thicknessDetectionModel.BackThicknessResult2 = list.Find(f => f.DetectedType == "BCT2")?.DetectedStatus == 1 ? true : false;
                    thicknessDetectionModel.BackThicknessResult3 = list.Find(f => f.DetectedType == "BCT3")?.DetectedStatus == 1 ? true : false;
                    thicknessDetectionModel.BackThicknessResult4 = list.Find(f => f.DetectedType == "BCT4")?.DetectedStatus == 1 ? true : false;
                    thicknessDetectionModel.BackThicknessResult5 = list.Find(f => f.DetectedType == "BCT5")?.DetectedStatus == 1 ? true : false;
                    thicknessDetectionModel.BackThicknessResult6 = list.Find(f => f.DetectedType == "BCT6")?.DetectedStatus == 1 ? true : false;
                    thicknessDetectionModel.BackThicknessResult7 = list.Find(f => f.DetectedType == "BCT7")?.DetectedStatus == 1 ? true : false;
                    thicknessDetectionModel.Crfront1WaveDistanceResult = JudgeIndicatorToleranceZone(list.Find(f => f.DetectedType == "FtFS")?.DetectedData?.ToString(), _indicatorToleranceZoneModelList.FirstOrDefault(p => p.Content.Contains("FtFS")));
                    thicknessDetectionModel.Crfront64WaveDistanceResult = JudgeIndicatorToleranceZone(list.Find(f => f.DetectedType == "FtLS")?.DetectedData?.ToString(), _indicatorToleranceZoneModelList.FirstOrDefault(p => p.Content.Contains("FtLS")));
                    thicknessDetectionModel.CrlargeEndDistanceResult = JudgeIndicatorToleranceZone(list.Find(f => f.DetectedType == "BtFS")?.DetectedData?.ToString(), _indicatorToleranceZoneModelList.FirstOrDefault(p => p.Content.Contains("BtFS")));
                    thicknessDetectionModel.CrsmallEndDistanceResult = JudgeIndicatorToleranceZone(list.Find(f => f.DetectedType == "BtLS")?.DetectedData?.ToString(), _indicatorToleranceZoneModelList.FirstOrDefault(p => p.Content.Contains("BtLS")));
                }
                thicknessDetectionModel.detaillist.AddRange(list);
                request = JsonConvert.SerializeObject(thicknessDetectionModel);
                AddLogEventHandler?.Invoke(channelCode + "数据存储内容：" + request);
                if (channelCode == "B")
                {
                    Thread.Sleep(500);
                }
                GetApiUtils.GetPostApi(request, sysModel.webApiUrl + "api/ThicknessDetection/Add").GetAwaiter();
                return MessageInfoUtils.Success();
            }
            catch (Exception ex)
            {
                AddLogEventHandler?.Invoke(channelCode + "数据存储报备：" + ex.ToString());
            }
            return MessageInfoUtils.Fail();
        }

        /// <summary>
        /// 线激光数据保存
        /// </summary>
        /// <param name="lineLaserData"></param>
        /// <param name="channelCode"></param>
        /// <param name="parentID"></param>
        /// <param name="indicatorToleranceZonesList"></param>
        private async Task<List<DetectionDetail>> LineLaserDataSave(KeyenceDataNew lineLaserData, string channelCode, int? channel_topc, string partcode,/*Guid parentID,*/ IEnumerable<IndicatorToleranceZoneModel> indicatorToleranceZonesList)
        {
            List<DetectionDetail> details = new();
            foreach (var item in lineLaserData.circleDiameter)
            {
                details.Add(LineLaserDataItem(item, channelCode, channel_topc, partcode/*parentID*/, 1/*GetResultValue(item.Key, item.Value, indicatorToleranceZonesList)*/));
            }
            foreach (var item in lineLaserData.centerDistance)
            {
                details.Add(LineLaserDataItem(item, channelCode, channel_topc, partcode/*parentID*/, 1/*GetResultValue(item.Key, item.Value, indicatorToleranceZonesList)*/));
            }
            foreach (var item in lineLaserData.backCircleDiameter)
            {
                details.Add(LineLaserDataItem(item, channelCode, channel_topc, partcode/*parentID*/, 1/*GetResultValue(item.Key, item.Value, indicatorToleranceZonesList)*/));
            }
            foreach (var item in lineLaserData.backCenterDistance)
            {
                details.Add(LineLaserDataItem(item, channelCode, channel_topc, partcode/*parentID*/, 1/*GetResultValue(item.Key, item.Value, indicatorToleranceZonesList)*/));
            }
            if (channelCode == "A")
            {
                foreach (var item in DataShift.FrontThicknessA)
                {
                    details.Add(ThicknessDataItem(item, channelCode, channel_topc, partcode/*parentID*/, await GetThicknessResultValue(item.Key, item.Value, indicatorToleranceZonesList)));
                }
                foreach (var item in DataShift.BackThicknessA)
                {
                    details.Add(ThicknessDataItem(item, channelCode, channel_topc, partcode/*parentID*/, await GetThicknessResultValue(item.Key, item.Value, indicatorToleranceZonesList)));
                }
            }
            else if (channelCode == "B")
            {
                await Task.Delay(500);
                foreach (var item in DataShift.FrontThicknessB)
                {
                    details.Add(ThicknessDataItem(item, channelCode, channel_topc, partcode/*parentID*/, await GetThicknessResultValue(item.Key, item.Value, indicatorToleranceZonesList)));
                }
                foreach (var item in DataShift.BackThicknessB)
                {
                    details.Add(ThicknessDataItem(item, channelCode, channel_topc, partcode/*parentID*/, await GetThicknessResultValue(item.Key, item.Value, indicatorToleranceZonesList)));
                }
            }
            //string requst = JsonConvert.SerializeObject(details);
            //GetApiUtils.GetPostApi(requst, sysModel.webApiUrl + "api/ThicknessDetection/KeyenceAdd").GetAwaiter().GetResult();
            return details;
        }

        /// <summary>
        /// 线激光数据项整合
        /// </summary>
        /// <param name="item">键值对</param>
        /// <param name="channelCode">通道代号</param>
        /// <param name="parentID">父ID</param>
        /// <param name="DetectedStatus">检测状态1：OK 2：NG</param>
        /// <returns></returns>
        private DetectionDetail LineLaserDataItem(KeyValuePair<string, string> item, string channelCode, int? channel_topc, string partcode/*Guid parentID*/, int DetectedStatus)
        {
            string channelDetails = ParseChannel(channel_topc, channelCode);//区分详细A1，A2，B1，B2
            /*return*/
            DetectionDetail instance = new DetectionDetail()
            {
                DetectedData = float.Parse(item.Value),
                DetectedType = item.Key,
                DetectedIndex = 25,
                DetectedTypeDisplay = StringUtils.GetDataDisPlay(item.Key),
                Plcip = "OP30",
                DetectedStatus = DetectedStatus,
                //ParentId = parentID,
                PartCode = partcode,
                Description = channelDetails
            };
            #region 增加补偿A1B1
            if (channelDetails == "A1")
            {
                if (item.Key.Contains("FS"))
                {
                    instance.DetectedData += (float)paraInstance.FSOffsetA;
                }
                if (item.Key.Contains("FD"))
                {
                    instance.DetectedData += (float)paraInstance.FDOffsetA;
                }
                if (item.Key.Contains("BS"))
                {
                    instance.DetectedData += (float)paraInstance.BSOffsetA;
                }
                if (item.Key.Contains("BD"))
                {
                    instance.DetectedData += (float)paraInstance.BDOffsetA;
                }
                if (item.Key.Contains("FtFS"))
                {
                    instance.DetectedData += (float)paraInstance.SC01OffsetA;
                }
                if (item.Key.Contains("FtLS"))
                {
                    instance.DetectedData += (float)paraInstance.SC02OffsetA;
                }
                if (item.Key.Contains("BtFS"))
                {
                    instance.DetectedData += (float)paraInstance.SC03OffsetA;
                }
                if (item.Key.Contains("BtLS"))
                {
                    instance.DetectedData += (float)paraInstance.SC04OffsetA;
                }
            }
            if (channelDetails == "B1")
            {
                if (item.Key.Contains("FS"))
                {
                    instance.DetectedData += (float)paraInstance.FSOffsetB;
                }
                if (item.Key.Contains("FD"))
                {
                    instance.DetectedData += (float)paraInstance.FDOffsetB;
                }
                if (item.Key.Contains("BS"))
                {
                    instance.DetectedData += (float)paraInstance.BSOffsetB;
                }
                if (item.Key.Contains("BD"))
                {
                    instance.DetectedData += (float)paraInstance.BDOffsetB;
                }
                if (item.Key.Contains("FtFS"))
                {
                    instance.DetectedData += (float)paraInstance.SC01OffsetB;
                }
                if (item.Key.Contains("FtLS"))
                {
                    instance.DetectedData += (float)paraInstance.SC02OffsetB;
                }
                if (item.Key.Contains("BtFS"))
                {
                    instance.DetectedData += (float)paraInstance.SC03OffsetB;
                }
                if (item.Key.Contains("BtLS"))
                {
                    instance.DetectedData += (float)paraInstance.SC04OffsetB;
                }
            }
            #endregion
            #region 增加补偿A2B2
            if (channelDetails == "A2")
            {
                if (item.Key.Contains("FS"))
                {
                    instance.DetectedData += (float)paraInstance.FSOffsetA2;
                }
                if (item.Key.Contains("FD"))
                {
                    instance.DetectedData += (float)paraInstance.FDOffsetA2;
                }
                if (item.Key.Contains("BS"))
                {
                    instance.DetectedData += (float)paraInstance.BSOffsetA2;
                }
                if (item.Key.Contains("BD"))
                {
                    instance.DetectedData += (float)paraInstance.BDOffsetA2;
                }
                if (item.Key.Contains("FtFS"))
                {
                    instance.DetectedData += (float)paraInstance.SC01OffsetA2;
                }
                if (item.Key.Contains("FtLS"))
                {
                    instance.DetectedData += (float)paraInstance.SC02OffsetA2;
                }
                if (item.Key.Contains("BtFS"))
                {
                    instance.DetectedData += (float)paraInstance.SC03OffsetA2;
                }
                if (item.Key.Contains("BtLS"))
                {
                    instance.DetectedData += (float)paraInstance.SC04OffsetA2;
                }
            }
            if (channelDetails == "B2")
            {
                if (item.Key.Contains("FS"))
                {
                    instance.DetectedData += (float)paraInstance.FSOffsetB2;
                }
                if (item.Key.Contains("FD"))
                {
                    instance.DetectedData += (float)paraInstance.FDOffsetB2;
                }
                if (item.Key.Contains("BS"))
                {
                    instance.DetectedData += (float)paraInstance.BSOffsetB2;
                }
                if (item.Key.Contains("BD"))
                {
                    instance.DetectedData += (float)paraInstance.BDOffsetB2;
                }
                if (item.Key.Contains("FtFS"))
                {
                    instance.DetectedData += (float)paraInstance.SC01OffsetB2;
                }
                if (item.Key.Contains("FtLS"))
                {
                    instance.DetectedData += (float)paraInstance.SC02OffsetB2;
                }
                if (item.Key.Contains("BtFS"))
                {
                    instance.DetectedData += (float)paraInstance.SC03OffsetB2;
                }
                if (item.Key.Contains("BtLS"))
                {
                    instance.DetectedData += (float)paraInstance.SC04OffsetB2;
                }
            }
            #endregion
            return instance;
        }

        /// <summary>
        /// 膜厚数据项整合
        /// </summary>
        /// <param name="item">键值对</param>
        /// <param name="channelCode">通道号</param>
        /// <param name="parentID">父ID</param>
        /// <param name="DetectedStatus">检测状态1：OK 2：NG</param>
        /// <returns></returns>
        private DetectionDetail ThicknessDataItem(KeyValuePair<string, string> item, string channelCode, int? channel_topc, string partcode,/* Guid parentID,*/ int DetectedStatus)
        {
            string channelDetails = ParseChannel(channel_topc, channelCode);//区分详细A1，A2，B1，B2
            /*return*/
            DetectionDetail instance = new DetectionDetail()
            {
                DetectedData = float.Parse(item.Value),
                DetectedType = item.Key,
                DetectedIndex = 24,
                DetectedTypeDisplay = StringUtils.GetDataDisPlay(item.Key),
                Plcip = "OP30",
                DetectedStatus = DetectedStatus,
                //ParentId = parentID,
                PartCode = partcode,
                Description = channelDetails
            };
            #region A1B1通道
            if (channelCode == "A1")
            {
                if (item.Key == "FCT1")
                {
                    instance.DetectedData += (float)paraInstance.FCT1OffsetA;
                }
                if (item.Key == "FCT2")
                {
                    instance.DetectedData += (float)paraInstance.FCT2OffsetA;
                }
                if (item.Key == "FCT3")
                {
                    instance.DetectedData += (float)paraInstance.FCT3OffsetA;
                }
                if (item.Key == "FCT4")
                {
                    instance.DetectedData += (float)paraInstance.FCT4OffsetA;
                }
                if (item.Key == "FCT5")
                {
                    instance.DetectedData += (float)paraInstance.FCT5OffsetB;
                }
                if (item.Key == "FCT6")
                {
                    instance.DetectedData += (float)paraInstance.FCT6OffsetA;
                }
                if (item.Key == "FCT7")
                {
                    instance.DetectedData += (float)paraInstance.FCT7OffsetA;
                }
                if (item.Key == "FCT8")
                {
                    instance.DetectedData += (float)paraInstance.FCT8OffsetA;
                }
                if (item.Key == "BCT1")
                {
                    instance.DetectedData += (float)paraInstance.BCT1OffsetA;
                }
                if (item.Key == "BCT2")
                {
                    instance.DetectedData += (float)paraInstance.BCT2OffsetA;
                }
                if (item.Key == "BCT3")
                {
                    instance.DetectedData += (float)paraInstance.BCT3OffsetA;
                }
                if (item.Key == "BCT4")
                {
                    instance.DetectedData += (float)paraInstance.BCT4OffsetA;
                }
                if (item.Key == "BCT5")
                {
                    instance.DetectedData += (float)paraInstance.BCT5OffsetB;
                }
                if (item.Key == "BCT6")
                {
                    instance.DetectedData += (float)paraInstance.BCT6OffsetA;
                }
                if (item.Key == "BCT7")
                {
                    instance.DetectedData += (float)paraInstance.BCT7OffsetA;
                }
                if (item.Key == "BCT8")
                {
                    instance.DetectedData += (float)paraInstance.BCT8OffsetA;
                }
            }
            if (channelCode == "B1")
            {
                if (item.Key == "FCT1")
                {
                    instance.DetectedData += (float)paraInstance.FCT1OffsetB;
                }
                if (item.Key == "FCT2")
                {
                    instance.DetectedData += (float)paraInstance.FCT2OffsetB;
                }
                if (item.Key == "FCT3")
                {
                    instance.DetectedData += (float)paraInstance.FCT3OffsetB;
                }
                if (item.Key == "FCT4")
                {
                    instance.DetectedData += (float)paraInstance.FCT4OffsetB;
                }
                if (item.Key == "FCT5")
                {
                    instance.DetectedData += (float)paraInstance.FCT5OffsetB;
                }
                if (item.Key == "FCT6")
                {
                    instance.DetectedData += (float)paraInstance.FCT6OffsetB;
                }
                if (item.Key == "FCT7")
                {
                    instance.DetectedData += (float)paraInstance.FCT7OffsetB;
                }
                if (item.Key == "FCT8")
                {
                    instance.DetectedData += (float)paraInstance.FCT8OffsetB;
                }
                if (item.Key == "BCT1")
                {
                    instance.DetectedData += (float)paraInstance.BCT1OffsetB;
                }
                if (item.Key == "BCT2")
                {
                    instance.DetectedData += (float)paraInstance.BCT2OffsetB;
                }
                if (item.Key == "BCT3")
                {
                    instance.DetectedData += (float)paraInstance.BCT3OffsetB;
                }
                if (item.Key == "BCT4")
                {
                    instance.DetectedData += (float)paraInstance.BCT4OffsetB;
                }
                if (item.Key == "BCT5")
                {
                    instance.DetectedData += (float)paraInstance.BCT5OffsetB;
                }
                if (item.Key == "BCT6")
                {
                    instance.DetectedData += (float)paraInstance.BCT6OffsetB;
                }
                if (item.Key == "BCT7")
                {
                    instance.DetectedData += (float)paraInstance.BCT7OffsetB;
                }
                if (item.Key == "BCT8")
                {
                    instance.DetectedData += (float)paraInstance.BCT8OffsetB;
                }
            }
            #endregion
            #region A2B2通道
            if (channelCode == "A2")
            {
                if (item.Key == "FCT1")
                {
                    instance.DetectedData += (float)paraInstance.FCT1OffsetA2;
                }
                if (item.Key == "FCT2")
                {
                    instance.DetectedData += (float)paraInstance.FCT2OffsetA2;
                }
                if (item.Key == "FCT3")
                {
                    instance.DetectedData += (float)paraInstance.FCT3OffsetA2;
                }
                if (item.Key == "FCT4")
                {
                    instance.DetectedData += (float)paraInstance.FCT4OffsetA2;
                }
                if (item.Key == "FCT5")
                {
                    instance.DetectedData += (float)paraInstance.FCT5OffsetB2;
                }
                if (item.Key == "FCT6")
                {
                    instance.DetectedData += (float)paraInstance.FCT6OffsetA2;
                }
                if (item.Key == "FCT7")
                {
                    instance.DetectedData += (float)paraInstance.FCT7OffsetA2;
                }
                if (item.Key == "FCT8")
                {
                    instance.DetectedData += (float)paraInstance.FCT8OffsetA2;
                }
                if (item.Key == "BCT1")
                {
                    instance.DetectedData += (float)paraInstance.BCT1OffsetA2;
                }
                if (item.Key == "BCT2")
                {
                    instance.DetectedData += (float)paraInstance.BCT2OffsetA2;
                }
                if (item.Key == "BCT3")
                {
                    instance.DetectedData += (float)paraInstance.BCT3OffsetA2;
                }
                if (item.Key == "BCT4")
                {
                    instance.DetectedData += (float)paraInstance.BCT4OffsetA2;
                }
                if (item.Key == "BCT5")
                {
                    instance.DetectedData += (float)paraInstance.BCT5OffsetB2;
                }
                if (item.Key == "BCT6")
                {
                    instance.DetectedData += (float)paraInstance.BCT6OffsetA2;
                }
                if (item.Key == "BCT7")
                {
                    instance.DetectedData += (float)paraInstance.BCT7OffsetA2;
                }
                if (item.Key == "BCT8")
                {
                    instance.DetectedData += (float)paraInstance.BCT8OffsetA2;
                }
            }
            if (channelCode == "B2")
            {
                if (item.Key == "FCT1")
                {
                    instance.DetectedData += (float)paraInstance.FCT1OffsetB2;
                }
                if (item.Key == "FCT2")
                {
                    instance.DetectedData += (float)paraInstance.FCT2OffsetB2;
                }
                if (item.Key == "FCT3")
                {
                    instance.DetectedData += (float)paraInstance.FCT3OffsetB2;
                }
                if (item.Key == "FCT4")
                {
                    instance.DetectedData += (float)paraInstance.FCT4OffsetB2;
                }
                if (item.Key == "FCT5")
                {
                    instance.DetectedData += (float)paraInstance.FCT5OffsetB2;
                }
                if (item.Key == "FCT6")
                {
                    instance.DetectedData += (float)paraInstance.FCT6OffsetB2;
                }
                if (item.Key == "FCT7")
                {
                    instance.DetectedData += (float)paraInstance.FCT7OffsetB2;
                }
                if (item.Key == "FCT8")
                {
                    instance.DetectedData += (float)paraInstance.FCT8OffsetB2;
                }
                if (item.Key == "BCT1")
                {
                    instance.DetectedData += (float)paraInstance.BCT1OffsetB2;
                }
                if (item.Key == "BCT2")
                {
                    instance.DetectedData += (float)paraInstance.BCT2OffsetB2;
                }
                if (item.Key == "BCT3")
                {
                    instance.DetectedData += (float)paraInstance.BCT3OffsetB2;
                }
                if (item.Key == "BCT4")
                {
                    instance.DetectedData += (float)paraInstance.BCT4OffsetB2;
                }
                if (item.Key == "BCT5")
                {
                    instance.DetectedData += (float)paraInstance.BCT5OffsetB2;
                }
                if (item.Key == "BCT6")
                {
                    instance.DetectedData += (float)paraInstance.BCT6OffsetB2;
                }
                if (item.Key == "BCT7")
                {
                    instance.DetectedData += (float)paraInstance.BCT7OffsetB2;
                }
                if (item.Key == "BCT8")
                {
                    instance.DetectedData += (float)paraInstance.BCT8OffsetB2;
                }
            }
            #endregion
            return instance;
        }

        /// <summary>
        /// 获取结果值
        /// </summary>
        /// <param name="key">键名</param>
        /// <param name="value">值</param>
        /// <param name="indicatorToleranceZonesList">公差带配置</param>
        /// <returns>1：OK 2：NG</returns>
        private int GetResultValue(string key, string value, IEnumerable<IndicatorToleranceZoneModel> indicatorToleranceZonesList)
        {
            string searchStr = key.Substring(0, 2);
            var indicatorInfo = indicatorToleranceZonesList.FirstOrDefault(p => p.Content.Contains(searchStr));
            var result = JudgeIndicatorToleranceZone(value, indicatorInfo);
            if (result)
            {
                return 1;
            }
            else
                return 0;
        }

        /// <summary>
        /// 获取膜厚结果
        /// </summary>
        /// <param name="key">键名</param>
        /// <param name="value">值</param>
        /// <param name="indicatorToleranceZonesList">公差带配置</param>
        /// <returns></returns>
        private async Task<int> GetThicknessResultValue(string key, string value, IEnumerable<IndicatorToleranceZoneModel> indicatorToleranceZonesList)
        {
            string searchStr = key.Substring(0, 3);
            var indicatorInfo = indicatorToleranceZonesList.FirstOrDefault(p => p.Content.Contains(searchStr));//.FirstOrDefault(p => p.Content.Contains(key));
            var result = await JudgeThicknessIndicatorToleranceZone(value, indicatorInfo);
            if (result)
            {
                return 1;
            }
            else
                return 0;
        }

        /// <summary>
        /// PLC上传更新数据
        /// </summary>
        /// <param name="plc">plc对象</param>
        /// <param name="channelCode">通道代号</param>
        /// <returns></returns>
        private async Task<ResultReturn> PlcUploadData(PLCController plc, string channelCode, int? channel_topc)
        {
            if (plc != null)
            {
                int dataStartAdrOffset = 0;//读取偏移量起始地址
                string sn = "";
                string[] strAry = new string[2];
                switch (channelCode.ToUpper())
                {
                    case "A":
                        strAry = SignalAdrSetting.SerialNumberA_OP30.Split('.');
                        sn = plc.ReadString(SignalAdrSetting.dbOp30, Convert.ToInt32(strAry[0]), Convert.ToInt32(strAry[1]));
                        break;

                    case "B":
                        strAry = SignalAdrSetting.SerialNumberB_OP30.Split('.');
                        sn = plc.ReadString(SignalAdrSetting.dbOp30, Convert.ToInt32(strAry[0]), Convert.ToInt32(strAry[1]));
                        break;
                }
                AddLogEventHandler?.Invoke(channelCode + "件OP30产品二维码：" + sn);
                List<DetectionDetail> details = new List<DetectionDetail>();
                Dictionary<string, int> detectionTypeList = new();
                detectionTypeList = StringUtils.GetDataOffset("OP30");

                bool? detectionResult_Camber = false;//获取Camber检测结果
                bool? thicknessDetectionResult = false;//膜厚检测结果
                switch (channelCode.ToUpper())
                {
                    case "A":
                        dataStartAdrOffset = SignalAdrSetting.dataStartOffsetA_OP30;
                        detectionResult_Camber = plc.ReadIntOne(SignalAdrSetting.dbOp30, Convert.ToInt32(SignalAdrSetting.CamberResultA)) == 1 ? true : false;
                        thicknessDetectionResult = DataShift.ThicknessAResult;
                        break;

                    case "B":
                        dataStartAdrOffset = SignalAdrSetting.dataStartOffsetB_OP30;
                        detectionResult_Camber = plc.ReadIntOne(SignalAdrSetting.dbOp30, Convert.ToInt32(SignalAdrSetting.CamberResultA)) == 1 ? true : false;
                        thicknessDetectionResult = DataShift.ThicknessBResult;
                        break;
                }
                details.AddRange(await UploadDataReal(plc, channelCode, SignalAdrSetting.dbOp30, dataStartAdrOffset, detectionTypeList, "OP30", sn, 0));

                //立面拱曲度检测结果
                bool facedCurvatureResult = channelCode == "A" ? (plc.ReadIntOne(SignalAdrSetting.dbOp30, Convert.ToInt32(SignalAdrSetting.CamberResultA)) == 1 ? true : false) : (plc.ReadIntOne(SignalAdrSetting.dbOp30, Convert.ToInt32(SignalAdrSetting.CamberResultB)) == 1 ? true : false);
                //bool totalResult = thicknessDetectionResult == true && facedCurvatureResult == true && _lineLaserResult == true;//总结果  膜厚+3D+立面
                bool totalResult = channelCode == "A" ? (plc.ReadIntOne(SignalAdrSetting.dbOp30, Convert.ToInt32(SignalAdrSetting.FinalResultA_OP30)) == 1 ? true : false) : (plc.ReadIntOne(SignalAdrSetting.dbOp30, Convert.ToInt32(SignalAdrSetting.FinalResultB_OP30)) == 1 ? true : false);
                string channelDetails = ParseChannel(channel_topc, channelCode);//区分详细A1，A2，B1，B2
                ThicknessDetectionModel TDModel = new()
                {
                    StationCode = "OP30",
                    PartCode = sn,
                    FrontThicknessResult1 = thicknessDetectionResult,
                    FacadeCurvatureResult = facedCurvatureResult,
                    _3dscannerResult1 = _lineLaserResult,
                    RunType = channelDetails/*channelCode*/,
                    Result = totalResult,
                    detaillist = details
                };
                return MessageInfoUtils.Success(TDModel);
            }
            return MessageInfoUtils.Fail();
        }

        /// <summary>
        /// 批量读取检测数据
        /// </summary>
        /// <param name="plc">plc对象</param>
        /// <param name="channelCode">通道号</param>
        /// <param name="db">DB块</param>
        /// <param name="dataStartOffset">数据起始便宜</param>
        /// <param name="contentTypeList">字典</param>
        /// <param name="dataSource">数据来源</param>
        /// <param name="partcode">产品二维码</param>
        /// <param name="detectedStatus">检测项状态</param>
        /// <returns></returns>
        private async Task<List<DetectionDetail>>? UploadDataReal(PLCController plc, string channelCode, int db, int dataStartOffset, Dictionary<string, int> contentTypeList, string dataSource, string partcode, int detectedStatus)
        {
            List<DetectionDetail> details = new();
            try
            {
                // 115个Real类型数据，每个数据占4个字节
                int numBytes = contentTypeList.Count * 4;
                byte[] dataS = plc.ReadBytes(db, dataStartOffset, numBytes);

                // 每个Real类型数据占4个字节
                float[] dataRead = new float[numBytes / 4];
                for (int i = 0; i < dataRead.Length; i++)
                {
                    byte[] floatData = new byte[4];
                    // 从原始数据中复制出一个 float 长度的数据块
                    Array.Copy(dataS, i * 4, floatData, 0, 4);
                    // 反转字节顺序
                    Array.Reverse(floatData);
                    dataRead[i] = BitConverter.ToSingle(floatData, 0);
                }
                string result = string.Join(",", dataRead);
                //Log4NetAppend(runType.ToString() + "件获取PLC地址值：" + result, dataIp);
                AddLogEventHandler?.Invoke(channelCode + "件OP30获取PLC地址值：" + result);
                for (int i = 0; i < contentTypeList.Count; i++)
                {
                    var contentType = contentTypeList.ElementAt(i);
                    details.Add(new DetectionDetail()
                    {
                        DetectedData = (float)Math.Round(dataRead[i], 3),
                        DetectedType = contentType.Key,//查找值名称
                        DetectedIndex = contentType.Value,
                        DetectedTypeDisplay = StringUtils.GetDataDisPlay(contentType.Key),//通过通用字符查找
                        Plcip = dataSource,
                        PartCode = partcode,
                        DetectedStatus = detectedStatus,
                        Description = channelCode
                    });
                }
            }
            catch (Exception ex)
            {
                AddLogEventHandler?.Invoke(channelCode + "件OP30使用批量获取测试时出错：" + ex.ToString(), dataSource);
            }
            return details;
        }

        /// <summary>
        /// 返回线激光结果
        /// </summary>
        /// <param name="plc">plc对象</param>
        /// <param name="channelCode">通道代号</param>
        /// <param name="result">结果 1：OK 2：NG 0：初始</param>
        private async Task ReturnLineLaserResult(PLCController plc, string channelCode, int result)
        {
            switch (channelCode.ToUpper())
            {
                case "A":
                    //plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.LineLaserWorkA, result);
                    await Task.Delay(200);
                    plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.LineLaserResultA, result);
                    break;

                case "B":
                    //plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.LineLaserWorkB, result);
                    await Task.Delay(200);
                    plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.LineLaserResultB, result);
                    break;
            }
        }

        ///// <summary>
        ///// 反馈3D设备状态
        ///// </summary>
        ///// <param name="plc"></param>
        ///// <param name="devStatus">设备状态</param>
        //private void ReturnLineLaserDeviceState(PLCController plc, LineLaserDeviceStatus devStatus)
        //{
        //    for (int i = 0; i < 4; i++)
        //    {
        //        if (i == 0)
        //        {
        //            plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.LineLaserDev1Ready, Convert.ToInt32(devStatus.LineLaser1DeviceStatus));
        //        }
        //        if (i == 1)
        //        {
        //            plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.LineLaserDev2Ready, Convert.ToInt32(devStatus.LineLaser2DeviceStatus));
        //        }
        //        if (i == 2)
        //        {
        //            plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.LineLaserDev3Ready, Convert.ToInt32(devStatus.LineLaser3DeviceStatus));
        //        }
        //        if (i == 3)
        //        {
        //            plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.LineLaserDev4Ready, Convert.ToInt32(devStatus.LineLaser4DeviceStatus));
        //        }
        //    }
        //}

        /// <summary>
        /// 线激光获取数据并判断数据是否合格
        /// </summary>
        /// <param name="plc">plc对象</param>
        /// <param name="channelCode">通道代号</param>
        /// <returns></returns>
        private async Task<KeyenceDataNew> LineLaserGetDataAndJudgement(PLCController plc, List<IndicatorToleranceZoneModel> parameter, string channelCode, string channelValue)
        {
            var lineLaserDataResult = await LineLaserGetData(channelCode, channelValue);
            if (lineLaserDataResult != null && lineLaserDataResult.Code == 1)
            {
                var lineLaserDataModels = (KeyenceDataNew)lineLaserDataResult.Data;
                bool result = ForeachIndicatorToleranceZone(lineLaserDataModels, parameter);
                _lineLaserResult = result;
                AddLogEventHandler?.Invoke(channelCode + $"件线激光数据{result.ToString()}");
                //发送判断结果
                //SendLineLaserResultFeedback(plc, channelCode, result);
                await ReturnLineLaserResult(plc, channelCode, result == true ? 1 : 2);
                return lineLaserDataModels;
            }
            else
            {
                await ReturnLineLaserResult(plc, channelCode, 2);
            }
            return new KeyenceDataNew();
        }

        /// <summary>
        /// 获取膜厚数据并判定是否在合理区间内
        /// </summary>
        /// <param name="plc">PLC对象</param>
        /// <param name="data">数据</param>
        /// <param name="parameter">公差带</param>
        /// <param name="channelCode"></param>
        /// <returns></returns>
        private async Task<bool> ThicknessGetDataAndJudgement(PLCController plc, DataNode[] data, List<IndicatorToleranceZoneModel> parameter, string channelCode)
        {
            if (data != null && data.Length > 0)
            {
                await GetThicknessData(data);
                bool result = ForeachThicknessIndicatorToleranceZone(channelCode, parameter).Result;
                await ReturnThciknessResultToPlc(plc, channelCode, result == true ? 1 : 2);
                return result;
            }
            else
            {
                return false;
            }
            return false;
        }

        private async Task ReturnThciknessResultToPlc(PLCController plc, string channelCode, int result)
        {
            switch (channelCode.ToUpper())
            {
                case "A":
                    await Task.Delay(200);
                    plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessResultA, result);
                    break;

                case "B":
                    await Task.Delay(200);
                    plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.ThicknessResultB, result);
                    break;
            }
        }

        /// <summary>
        /// 获取膜厚数据
        /// </summary>
        /// <param name="data"></param>
        private async Task GetThicknessData(DataNode[] data)
        {
            ///*
            // 去掉数组中前百分之10和后百分之10
            // 保留中间数据段
            // */
            //DataNode[] tempDataAry = new DataNode[data.Length];
            //if (data.Length > 0)
            //{
            //    int cutoutLength = Convert.ToInt32(data.Length * 0.1);//需要截取的长度
            //    Array.Copy(data, cutoutLength, tempDataAry, 0, Convert.ToInt32(data.Length - (cutoutLength * 2)));//截取头尾，保留中间段
            //}

            int i1 = 0;
            int i2 = 0;
            int i3 = 0;
            int i4 = 0;
            List<double> frontThicknessATotal = new List<double>();
            List<double> frontThicknessBTotal = new List<double>();
            List<double> backThicknessATotal = new List<double>();
            List<double> backThicknessBTotal = new List<double>();

            List<double> frontThicknessADis = new List<double>();
            List<double> frontThicknessBDis = new List<double>();
            List<double> backThicknessADis = new List<double>();
            List<double> backThicknessBDis = new List<double>();

            List<double> frontThicknessA = new List<double>();
            List<double> frontThicknessB = new List<double>();
            List<double> backThicknessA = new List<double>();
            List<double> backThicknessB = new List<double>();

            DataShift.FrontThicknessA.Clear();
            DataShift.FrontThicknessB.Clear();
            DataShift.BackThicknessA.Clear();
            DataShift.BackThicknessB.Clear();
            foreach (var item in data)
            {
                if (item.cfg.channel == 4)
                {
                    //frontThicknessA.Add(item.data);
                    frontThicknessATotal.Add(Convert.ToDouble(item.data));
                }
                else if (item.cfg.channel == 3)
                {
                    //backThicknessA.Add(item.data);
                    backThicknessATotal.Add(Convert.ToDouble(item.data));
                }
                if (item.cfg.channel == 2)
                {
                    //frontThicknessB.Add(item.data);
                    frontThicknessBTotal.Add(Convert.ToDouble(item.data));
                }
                else if (item.cfg.channel == 1)
                {
                    //backThicknessB.Add(item.data);
                    backThicknessBTotal.Add(Convert.ToDouble(item.data));
                }
            }

            var frontA = await ParseDistanceAndThickness(frontThicknessATotal);
            var backA = await ParseDistanceAndThickness(backThicknessATotal);
            var frontB = await ParseDistanceAndThickness(frontThicknessBTotal);
            var backB = await ParseDistanceAndThickness(backThicknessBTotal);

            //DataShift.FrontThicknessA = await CalculateThicknessAlgorithmNew("FCT", frontA.Item1, frontA.Item2);
            //DataShift.BackThicknessA = await CalculateThicknessAlgorithmNew("BCT", backA.Item1, backA.Item2);
            //DataShift.FrontThicknessB = await CalculateThicknessAlgorithmNew("FCT", frontB.Item1, frontB.Item2);
            //DataShift.BackThicknessB = await CalculateThicknessAlgorithmNew("BCT", backB.Item1, backB.Item2);

            DataShift.FrontThicknessA = await CalculateThicknessAlgorithmUsePulseNew("FCT", frontA.Item1, frontA.Item2);
            DataShift.BackThicknessA = await CalculateThicknessAlgorithmUsePulseNew("BCT", backA.Item1, backA.Item2);
            DataShift.FrontThicknessB = await CalculateThicknessAlgorithmUsePulseNew("FCT", frontB.Item1, frontB.Item2);
            DataShift.BackThicknessB = await CalculateThicknessAlgorithmUsePulseNew("BCT", backB.Item1, backB.Item2);
        }

        /// <summary>
        /// 解析存放膜厚和膜厚距离
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        private async Task<(List<double>, List<double>)> ParseDistanceAndThickness(List<double> list)
        {
            List<double> dis = new List<double>();
            List<double> thick = new List<double>();
            if (list.Any())
            {
                for (int i = 1; i <= list.Count; i++)
                {
                    if (i % 2 == 0)//存放膜厚
                    {
                        thick.Add(list[i - 1]);
                    }
                    else
                    {
                        dis.Add(list[i - 1]);
                    }
                }
                return (dis, thick);
            }
            return (null, null);
        }

        private bool Judge(double value)
        {
            if (value >= 0.10 && value <= 4)//0.5~3.6
            {
                return true;
            }
            return false;
        }

        #region 新计算膜厚算法使用脉冲（采集方式通过取多段夹持端数据）

        /// <summary>
        /// 计算膜厚算法使用脉冲
        /// </summary>
        /// <param name="detectionType">检测类型</param>
        /// <param name="dis">距离数组</param>
        /// <param name="thick">膜厚数组</param>
        /// <returns></returns>
        private async Task<Dictionary<string, string>> CalculateThicknessAlgorithmUsePulseNew(string detectionType, List<double> disList, List<double> thickList)
        {
            double temp = 0;//临时变量
            int findValidValueCount = 0;
            int idx = 0;
            //List<double> tempList = new List<double>();
            //List<double> tempThickList = new List<double>();
            List<SourceData> srcList = new List<SourceData>();
            List<int> pulsePosList = new List<int>();
            List<double> finalList = new List<double>();
            //Dictionary<string, WaveDetail> result = new Dictionary<string, WaveDetail>();
            Dictionary<string, string> result = new Dictionary<string, string>();
            for (int i = 0; i < 130; i++)
            {
                disList.Insert(0, -2147.483648);
                disList.Add(-2147.483648);
                thickList.Add(-2147.483648);
                thickList.Insert(0, -2147.483648);
            }
            foreach (var item in disList)
            {
                if (item == -2147.483648)
                {
                    findValidValueCount++;
                    if (findValidValueCount >= 120)//35
                    {
                        if (item != temp)
                        {
                            //tempList.Add(item);
                            //tempThickList.Add(thickList[idx]);
                            srcList.Add(new SourceData() { PulseCount = idx + 1, Distance = item, Thickness = thickList[idx] });
                            temp = item;
                            findValidValueCount = 0;
                        }
                    }
                }
                else
                {
                    if (item != temp && item != -2147.483648)
                    {
                        //tempList.Add(item);
                        //tempThickList.Add(thickList[idx]);
                        srcList.Add(new SourceData() { PulseCount = idx + 1, Distance = item, Thickness = thickList[idx] });
                        temp = item;
                        findValidValueCount = 0;
                    }
                }
                idx++;
            }

            int index = srcList.FindIndex(f => f.Distance == -2147.483648);
            int endIndex = 0;
            DateTime starttime = DateTime.Now;
            DateTime endtime = DateTime.Now;
            double timediff = 0;
            int count = 1;
            while (index != -1)
            {
                index = srcList.FindIndex(f => f.Distance == -2147.483648);/*tempList.IndexOf(-2147.483648);*/

                if (index != -1)//找到起始位置
                {
                    endIndex = srcList.FindIndex(index + 1, f => f.Distance == -2147.483648);/*tempList.IndexOf(-2147.483648, index + 1);*/
                    if (endIndex != -1)//找到结束位置
                    {
                        double totalValue = 0;
                        double thicknessValue = 0;
                        //double[] disArray =  tempList.GetRange(index + 1, endIndex - index - 1).ToArray();//有效距离数组
                        //double[] thickArray = tempThickList.GetRange(index + 1, endIndex - index - 1).ToArray();
                        List<SourceData> dstList = srcList.GetRange(index + 1, endIndex - index - 1);

                        List<double> disArrayList = new List<double>();
                        List<double> thickArrayList = new List<double>();
                        List<int> pulseArrayList = new List<int>();

                        foreach (var item in dstList)
                        {
                            disArrayList.Add(item.Distance);
                            thickArrayList.Add(item.Thickness);
                            pulseArrayList.Add(item.PulseCount);
                        }

                        double[] disArray = disArrayList.ToArray();
                        double[] thickArray = thickArrayList.ToArray();
                        int[] pulseArray = pulseArrayList.ToArray();

                        double[] avgAry = new double[10];
                        avgAry.Initialize();
                        int thickIndex = 0;
                        //if (detectionType.Contains("FCT"))
                        //{
                        //    thickIndex = disArray.ToList().FindIndex(f => f == disArray.Max());//找到膜厚下标
                        //}
                        //else
                        //{
                        //    thickIndex = disArray.ToList().FindIndex(f => f == disArray.Min());//找到膜厚下标
                        //}
                        thickIndex = disArray.ToList().FindIndex(f => f == disArray.Max());//找到膜厚下标
                        double diffZoneLeft = 0;
                        double diffZoneRight = 0;
                        try
                        {
                            if (thickIndex != -1)
                            {
                                diffZoneLeft = disArray[0] - disArray[thickIndex];
                                diffZoneRight = disArray[disArray.Length - 1] - disArray[thickIndex];
                            }
                            else
                            {
                                diffZoneLeft = 0;
                                diffZoneRight = 0;
                            }
                        }
                        catch
                        {
                            diffZoneLeft = 0;
                            diffZoneRight = 0;
                        }

                        bool resLeft = Judge(Math.Abs(diffZoneLeft));
                        bool resRight = Judge(Math.Abs(diffZoneRight));
                        AddLogEventHandler?.Invoke($"Left:{Math.Abs(diffZoneLeft)}:{resLeft.ToString()};Right:{Math.Abs(diffZoneRight)}:{resRight.ToString()}");
                        bool res = true;
                        ////if (count == 1 || count == 2)
                        ////{
                        if (resLeft && resRight)
                        {
                            res = true;
                        }
                        else
                        {
                            res = false;
                        }
                        ////}
                        if (res)
                        {
                            AddLogEventHandler?.Invoke("左右段差OK");
                            int currentPulse = 0;
                            int lastPulse = 0;
                            int diffPulse = 0;
                            thicknessValue = thickArray[thickIndex];/*CalculateAvgThicknessValue(thickIndex, thickArray, disArray, totalValue, avgAry);*/
                            if (thicknessValue.ToString() == "NaN")
                            {
                                thicknessValue = 0;
                            }
                            finalList.Add(thicknessValue);
                            count++;

                            //if (pulsePosList.Any())
                            //{
                            //    currentPulse = pulseArray[thickIndex];
                            //    lastPulse = pulsePosList.Last();
                            //    diffPulse = currentPulse - lastPulse;
                            //    if (diffPulse >= 600 && diffPulse <= 780)
                            //    {
                            //        pulsePosList.Add(pulseArray[thickIndex]);
                            //        thicknessValue = CalculateAvgThicknessValue(thickIndex, thickArray, disArray, totalValue, avgAry);
                            //        if (thicknessValue.ToString() == "NaN")
                            //        {
                            //            thicknessValue = 0;
                            //        }
                            //        finalList.Add(thicknessValue);
                            //        count++;
                            //    }
                            //    else if (diffPulse > 780)
                            //    {
                            //        int findIdx = pulsePosList.Last() + 1000;
                            //        pulsePosList.Add(findIdx);
                            //        int idxpulse = pulseArrayList.FindIndex(p => (p >= findIdx - 200 && p <= findIdx + 200));
                            //        if (idxpulse != -1)
                            //        {
                            //            thicknessValue = CalculateAvgThicknessValue(thickIndex, thickArray, disArray, totalValue, avgAry);
                            //            if (thicknessValue.ToString() == "NaN")
                            //            {
                            //                thicknessValue = 0;
                            //            }
                            //            finalList.Add(thicknessValue);
                            //            count++;
                            //        }
                            //        else
                            //        {
                            //            thicknessValue = 0;
                            //            finalList.Add(thicknessValue);
                            //            count++;
                            //        }
                            //    }
                            //}
                            //else
                            //{
                            //    pulsePosList.Add(pulseArray[thickIndex]);
                            //    thicknessValue = CalculateAvgThicknessValue(thickIndex, thickArray, disArray, totalValue, avgAry);
                            //    if (thicknessValue.ToString() == "NaN")
                            //    {
                            //        thicknessValue = 0;
                            //    }
                            //    finalList.Add(thicknessValue);
                            //    count++;
                            //}

                            //count++;
                        }
                        else
                        {
                            AddLogEventHandler?.Invoke("左右段差NG");
                        }
                        srcList.RemoveAt(index);
                    }
                    else
                    {
                        index = -1;
                    }
                }
                endtime = DateTime.Now;
                timediff = (endtime - starttime).TotalSeconds;
            }

            AddLogEventHandler?.Invoke($"膜厚数据大小：{finalList.Count}");

            int interval = finalList.Count / 3;//每个波之间的间隔
            int currentCount = 1;

            try
            {
                if (finalList.Any())
                {
                    for (int i = 0; i < 8/*finalList.Count*/; i++)
                    {
                        if (finalList.Count == 7 && i == 7)
                        {
                            result.Add($"{detectionType}{i + 1}", "9999");
                            AddLogEventHandler?.Invoke($"{detectionType}{i + 1}：" + "9999");
                        }
                        else
                        {
                            result.Add($"{detectionType}{i + 1}", finalList[i].ToString("0.000"));
                            AddLogEventHandler?.Invoke($"{detectionType}{i + 1}：" + finalList[i].ToString("0.000"));
                        }

                        //if (currentCount <= interval)
                        //{
                        //    if (currentCount > 1 && currentCount <= 4 && result.Count < 8)
                        //    {
                        //        if (result.Any())
                        //        {
                        //            result.Add($"{detectionType}{result.Count + 1}", finalList[i].ToString("0.000"));
                        //        }
                        //        else
                        //        {
                        //            result.Add($"{detectionType}1", finalList[i].ToString("0.000"));
                        //        }
                        //        AddLogEventHandler?.Invoke($"{detectionType}{result.Count}:" + finalList[i].ToString("0.000"));
                        //    }
                        //    currentCount++;
                        //}
                        //else
                        //{
                        //    currentCount = 1;
                        //}
                        //if (result.Count > 8)
                        //{
                        //    break;
                        //}

                        ////if (indexvalue[i] < finalList.Count)
                        ////{
                        ////    result.Add($"{detectionType}{i + 1}", finalList[indexvalue[i]].ToString("0.000"));
                        ////    AddLogEventHandler?.Invoke($"{detectionType}{i + 1}：" + finalList[indexvalue[i]].ToString("0.000"));
                        ////}
                        ////else
                        ////{
                        ////    result.Add($"{detectionType}{i + 1}", "0");
                        ////    AddLogEventHandler?.Invoke($"{detectionType}{i + 1}：" + "0-未扫完全");
                        ////}
                    }
                    AddLogEventHandler?.Invoke($"{detectionType}已添加完整膜厚数据");
                }
                else
                {
                    for (int i = 0; i < 8; i++)
                    {
                        result.Add($"{detectionType}{i + 1}", "0.000");
                        AddLogEventHandler?.Invoke($"{detectionType}{i + 1}：" + "0.000");
                    }
                    AddLogEventHandler?.Invoke($"{detectionType}膜厚数据未扫到，已将其全部赋值为0");
                }
            }
            catch (Exception ex)
            {
                result = new Dictionary<string, string>();
                for (int i = 0; i < 8; i++)
                {
                    result.Add($"{detectionType}{i + 1}", "0.000");
                }
                AddLogEventHandler?.Invoke($"膜厚数据异常，已清除所有数据");
            }
            return result;
        }

        #endregion

        #region 计算膜厚算法使用脉冲

        /// <summary>
        /// 计算膜厚算法使用脉冲
        /// </summary>
        /// <param name="detectionType">检测类型</param>
        /// <param name="dis">距离数组</param>
        /// <param name="thick">膜厚数组</param>
        /// <returns></returns>
        private async Task<Dictionary<string, string>> CalculateThicknessAlgorithmUsePulse(string detectionType, List<double> disList, List<double> thickList)
        {
            double temp = 0;//临时变量
            int findValidValueCount = 0;
            int idx = 0;
            //List<double> tempList = new List<double>();
            //List<double> tempThickList = new List<double>();
            List<SourceData> srcList = new List<SourceData>();
            List<int> pulsePosList = new List<int>();
            List<double> finalList = new List<double>();
            //Dictionary<string, WaveDetail> result = new Dictionary<string, WaveDetail>();
            Dictionary<string, string> result = new Dictionary<string, string>();
            foreach (var item in disList)
            {
                if (item == -2147.483648)
                {
                    findValidValueCount++;
                    if (findValidValueCount >= 120)//35
                    {
                        if (item != temp)
                        {
                            //tempList.Add(item);
                            //tempThickList.Add(thickList[idx]);
                            srcList.Add(new SourceData() { PulseCount = idx + 1, Distance = item, Thickness = thickList[idx] });
                            temp = item;
                            findValidValueCount = 0;
                        }
                    }
                }
                else
                {
                    if (item != temp && item != -2147.483648)
                    {
                        //tempList.Add(item);
                        //tempThickList.Add(thickList[idx]);
                        srcList.Add(new SourceData() { PulseCount = idx + 1, Distance = item, Thickness = thickList[idx] });
                        temp = item;
                        findValidValueCount = 0;
                    }
                }
                idx++;
            }

            int index = srcList.FindIndex(f => f.Distance == -2147.483648);
            int endIndex = 0;
            DateTime starttime = DateTime.Now;
            DateTime endtime = DateTime.Now;
            double timediff = 0;
            int count = 1;
            while (index != -1)
            {
                index = srcList.FindIndex(f => f.Distance == -2147.483648);/*tempList.IndexOf(-2147.483648);*/

                if (index != -1)//找到起始位置
                {
                    endIndex = srcList.FindIndex(index + 1, f => f.Distance == -2147.483648);/*tempList.IndexOf(-2147.483648, index + 1);*/
                    if (endIndex != -1)//找到结束位置
                    {
                        double totalValue = 0;
                        double thicknessValue = 0;
                        //double[] disArray =  tempList.GetRange(index + 1, endIndex - index - 1).ToArray();//有效距离数组
                        //double[] thickArray = tempThickList.GetRange(index + 1, endIndex - index - 1).ToArray();
                        List<SourceData> dstList = srcList.GetRange(index + 1, endIndex - index - 1);

                        List<double> disArrayList = new List<double>();
                        List<double> thickArrayList = new List<double>();
                        List<int> pulseArrayList = new List<int>();

                        foreach (var item in dstList)
                        {
                            disArrayList.Add(item.Distance);
                            thickArrayList.Add(item.Thickness);
                            pulseArrayList.Add(item.PulseCount);
                        }

                        double[] disArray = disArrayList.ToArray();
                        double[] thickArray = thickArrayList.ToArray();
                        int[] pulseArray = pulseArrayList.ToArray();

                        double[] avgAry = new double[50];
                        avgAry.Initialize();
                        int thickIndex = 0;
                        if (detectionType.Contains("FCT"))
                        {
                            thickIndex = disArray.ToList().FindIndex(f => f == disArray.Max());//找到膜厚下标
                        }
                        else
                        {
                            thickIndex = disArray.ToList().FindIndex(f => f == disArray.Min());//找到膜厚下标
                        }
                        double diffZoneLeft = 0;
                        double diffZoneRight = 0;
                        try
                        {
                            if (thickIndex != -1)
                            {
                                diffZoneLeft = disArray[0] - disArray[thickIndex];
                                diffZoneRight = disArray[disArray.Length - 1] - disArray[thickIndex];
                            }
                            else
                            {
                                diffZoneLeft = 0;
                                diffZoneRight = 0;
                            }
                        }
                        catch
                        {
                            diffZoneLeft = 0;
                            diffZoneRight = 0;
                        }

                        bool resLeft = Judge(Math.Abs(diffZoneLeft));
                        bool resRight = Judge(Math.Abs(diffZoneRight));
                        bool res = true;
                        if (count == 1 || count == 2)
                        {
                            if (resLeft && resRight)
                            {
                                res = true;
                            }
                            else
                            {
                                res = false;
                            }
                        }
                        if (res)
                        {
                            int currentPulse = 0;
                            int lastPulse = 0;
                            int diffPulse = 0;
                            if (pulsePosList.Any())
                            {
                                currentPulse = pulseArray[thickIndex];
                                lastPulse = pulsePosList.Last();
                                diffPulse = currentPulse - lastPulse;
                                if (diffPulse >= 600 && diffPulse <= 780)
                                {
                                    pulsePosList.Add(pulseArray[thickIndex]);
                                    thicknessValue = CalculateAvgThicknessValue(thickIndex, thickArray, disArray, totalValue, avgAry);
                                    if (thicknessValue.ToString() == "NaN")
                                    {
                                        thicknessValue = 0;
                                    }
                                    finalList.Add(thicknessValue);
                                    count++;
                                }
                                else if (diffPulse > 780)
                                {
                                    int findIdx = pulsePosList.Last() + 1000;
                                    pulsePosList.Add(findIdx);
                                    int idxpulse = pulseArrayList.FindIndex(p => (p >= findIdx - 200 && p <= findIdx + 200));
                                    if (idxpulse != -1)
                                    {
                                        thicknessValue = CalculateAvgThicknessValue(thickIndex, thickArray, disArray, totalValue, avgAry);
                                        if (thicknessValue.ToString() == "NaN")
                                        {
                                            thicknessValue = 0;
                                        }
                                        finalList.Add(thicknessValue);
                                        count++;
                                    }
                                    else
                                    {
                                        thicknessValue = 0;
                                        finalList.Add(thicknessValue);
                                        count++;
                                    }
                                }
                            }
                            else
                            {
                                pulsePosList.Add(pulseArray[thickIndex]);
                                thicknessValue = CalculateAvgThicknessValue(thickIndex, thickArray, disArray, totalValue, avgAry);
                                if (thicknessValue.ToString() == "NaN")
                                {
                                    thicknessValue = 0;
                                }
                                finalList.Add(thicknessValue);
                                count++;
                            }

                            //count++;
                        }
                        srcList.RemoveAt(index);
                    }
                    else
                    {
                        index = -1;
                    }
                }
                endtime = DateTime.Now;
                timediff = (endtime - starttime).TotalSeconds;
                //if (finalList.Count >= 48)
                //{
                //    break;
                //}
            }

            AddLogEventHandler?.Invoke($"膜厚数据大小：{finalList.Count}");
            //if (finalList.Count >= 27 && finalList.Count <= 48)
            //if (finalList.Count > 40)
            //{
            //int[] indexvalue = new int[] { };
            //if (finalList.Count >= 45)
            //{
            //int[] indexvalue = new int[] { 5, 6, 7, 24, 25, 26, 43, 44 };//需要获取的膜厚位置，意思第几个波
            int[] indexvalue = new int[] { 3, 4, 5, 23, 24, 25, 42, 43 };//需要获取的膜厚位置，意思第几个波

            for (int i = 0; i < indexvalue.Length/*finalList.Count*/; i++)
            {
                if (indexvalue[i] < finalList.Count)
                {
                    result.Add($"{detectionType}{i + 1}", finalList[indexvalue[i]].ToString("0.000"));
                    AddLogEventHandler?.Invoke($"{detectionType}{i + 1}：" + finalList[indexvalue[i]].ToString("0.000"));
                }
                else
                {
                    result.Add($"{detectionType}{i + 1}", "0");
                    AddLogEventHandler?.Invoke($"{detectionType}{i + 1}：" + "0-未扫完全");
                }
            }
            AddLogEventHandler?.Invoke($"{detectionType}已添加完整膜厚数据");
            return result;
            //return pulsePosList;
        }

        #endregion

        /// <summary>
        /// 求平均值膜厚
        /// </summary>
        /// <param name="thickIndex"></param>
        /// <param name="thickArray"></param>
        /// <param name="disArray"></param>
        /// <param name="totalValue"></param>
        /// <param name="avgAry"></param>
        /// <returns></returns>
        private double CalculateAvgThicknessValue(int thickIndex, double[] thickArray, double[] disArray, double totalValue, double[] avgAry)
        {
            for (int i = 0; i < 5; i++)
            {
                if (thickIndex + i < thickArray.Length - 1 && thickIndex - i < thickArray.Length - 1 /*&& thickIndex != 0*/ && thickIndex - i >= 0)
                {
                    double value = thickArray[thickIndex - i];
                    if (value != -2147.483648)
                    {
                        totalValue += value;
                        avgAry[i] = value;
                        if (thickArray[thickIndex + i] != -2147.483648)
                        {
                            double valueSum = thickArray[thickIndex + i];
                            totalValue += valueSum;
                            avgAry[4 + i] = valueSum;
                        }
                    }
                    else if (thickArray[thickIndex + i] != -2147.483648)
                    {
                        double valueSum1 = thickArray[thickIndex + i];
                        totalValue += valueSum1;
                        avgAry[4 + i] = valueSum1;
                    }
                }
            }
            double thicknessValue = totalValue / avgAry.Where(f => f != 0).ToArray().Length;//均值计算
            return thicknessValue;
        }

        #region 实验

        /// <summary>
        /// 计算膜厚算法 新
        /// </summary>
        /// <param name="detectionType">检测类型</param>
        /// <param name="dis">距离数组</param>
        /// <param name="thick">膜厚数组</param>
        /// <returns></returns>
        private async Task<Dictionary<string, string>> CalculateThicknessAlgorithmNew(string detectionType, List<double> disList, List<double> thickList)
        {
            //int deleteCount = Convert.ToInt32(ConfigurationManager.AppSettings["deleteCountMH"].ToString());
            //if (disList.Count > deleteCount)
            //{
            //    disList.RemoveRange(0, deleteCount - 1);
            //}
            //if (thickList.Count > deleteCount)
            //{
            //    thickList.RemoveRange(0, deleteCount - 1);
            //}
            double temp = 0;//临时变量
            int findValidValueCount = 0;
            int idx = 0;
            List<double> tempList = new List<double>();
            List<double> tempThickList = new List<double>();
            List<double> finalList = new List<double>();
            Dictionary<string, string> result = new Dictionary<string, string>();
            foreach (var item in disList)
            {
                if (item == -2147.483648)
                {
                    findValidValueCount++;
                    if (findValidValueCount >= 35)
                    {
                        if (item != temp)
                        {
                            tempList.Add(item);
                            tempThickList.Add(thickList[idx]);
                            temp = item;
                            findValidValueCount = 0;
                        }
                    }
                }
                else
                {
                    if (item != temp && item != -2147.483648)
                    {
                        tempList.Add(item);
                        tempThickList.Add(thickList[idx]);
                        temp = item;
                        findValidValueCount = 0;
                    }
                }
                idx++;
            }
            int index = tempList.IndexOf(-2147.483648);
            int endIndex = 0;
            DateTime starttime = DateTime.Now;
            DateTime endtime = DateTime.Now;
            double timediff = 0;
            ArithmeticMH arithmeticIns = GetArithmeticModel(arithmetic_MH);
            int listCount = 1;
            while (index != -1)
            {
                index = tempList.IndexOf(-2147.483648);
                if (index != -1)//找到起始位置
                {
                    endIndex = tempList.IndexOf(-2147.483648, index + 1);
                    if (endIndex != -1)//找到结束位置
                    {
                        double totalValue = 0;
                        double thicknessValue = 0;
                        double[] disArray = tempList.GetRange(index + 1, endIndex - index - 1).ToArray();//有效距离数组
                        double[] thickArray = tempThickList.GetRange(index + 1, endIndex - index - 1).ToArray();
                        double[] avgAry = new double[50];
                        avgAry.Initialize();
                        int thickIndex = 0;
                        if (detectionType.Contains("FCT"))
                        {
                            thickIndex = disArray.ToList().FindIndex(f => f == disArray.Max());//找到膜厚下标
                        }
                        else
                        {
                            thickIndex = disArray.ToList().FindIndex(f => f == disArray.Min());//找到膜厚下标
                        }
                        double diffZoneLeft = 0;
                        double diffZoneRight = 0;
                        try
                        {
                            if (thickIndex != -1)
                            {
                                diffZoneLeft = disArray[0] - disArray[thickIndex];
                                diffZoneRight = disArray[disArray.Length - 1] - disArray[thickIndex];
                            }
                            else
                            {
                                diffZoneLeft = 0;
                                diffZoneRight = 0;
                            }
                        }
                        catch
                        {
                            diffZoneLeft = 0;
                            diffZoneRight = 0;
                        }
                        bool resLeft = Judge(Math.Abs(diffZoneLeft));//判断波左边区间
                        bool resRight = Judge(Math.Abs(diffZoneRight));//判断波右边区间
                        bool res = true;
                        if (listCount == 1 || listCount == 2)//过滤小端头波
                        {
                            if (resLeft && resRight)
                            {
                                res = true;
                            }
                            else
                            {
                                res = false;
                            }
                        }
                        if (disArray.Length > 40 && res/*resLeft && resRight*/)
                        {
                            for (int i = 0; i < 25; i++)
                            {
                                if (thickIndex + i < thickArray.Length - 1 && thickIndex - i < thickArray.Length - 1 /*&& thickIndex != 0*/ && thickIndex - i >= 0)
                                {
                                    double value = thickArray[thickIndex - i];
                                    if (value != -2147.483648)
                                    {
                                        totalValue += value;
                                        avgAry[i] = value;
                                        if (thickArray[thickIndex + i] != -2147.483648)
                                        {
                                            double valueSum = thickArray[thickIndex + i];
                                            totalValue += valueSum;
                                            avgAry[24 + i] = valueSum;
                                        }
                                    }
                                    else if (thickArray[thickIndex + i] != -2147.483648)
                                    {
                                        double valueSum1 = thickArray[thickIndex + i];
                                        totalValue += valueSum1;
                                        avgAry[24 + i] = valueSum1;
                                    }
                                }
                            }
                            thicknessValue = totalValue / avgAry.Where(f => f != 0).ToArray().Length;//均值计算

                            if (thicknessValue.ToString() == "NaN")
                            {
                                thicknessValue = 0;
                            }
                            finalList.Add(thicknessValue);
                            listCount++;
                        }

                        tempList.RemoveAt(index);
                        tempThickList.RemoveAt(index);
                    }
                    else
                    {
                        index = -1;
                    }
                }
                endtime = DateTime.Now;
                timediff = (endtime - starttime).TotalSeconds;
                //if (timediff > timeoutValue/*50*/)
                //{
                //    break;
                //}
                //if (finalList.Count >= 48)
                //{
                //    break;
                //}
            }
            AddLogEventHandler?.Invoke($"膜厚数据大小：{finalList.Count}");
            //if (finalList.Count >= 27 && finalList.Count <= 48)
            //if (finalList.Count > 40)
            //{
            //int[] indexvalue = new int[] { };
            //if (finalList.Count >= 45)
            //{
            //int[] indexvalue = new int[] { 5, 6, 7, 24, 25, 26, 43, 44 };//需要获取的膜厚位置，意思第几个波
            int[] indexvalue = new int[] { 3, 4, 5, 23, 24, 25, 41, 42 };//需要获取的膜厚位置，意思第几个波

            for (int i = 0; i < indexvalue.Length/*finalList.Count*/; i++)
            {
                if (indexvalue[i] < finalList.Count)
                {
                    result.Add($"{detectionType}{i + 1}", finalList[indexvalue[i]].ToString("0.000"));
                    AddLogEventHandler?.Invoke($"{detectionType}{i + 1}：" + finalList[indexvalue[i]].ToString("0.000"));
                }
                else
                {
                    result.Add($"{detectionType}{i + 1}", "0");
                    AddLogEventHandler?.Invoke($"{detectionType}{i + 1}：" + "0-未扫完全");
                }
            }
            AddLogEventHandler?.Invoke($"{detectionType}已添加完整膜厚数据");
            return result;
        }

        /// <summary>
        /// 计算膜厚算法
        /// </summary>
        /// <param name="data">数据</param>
        /// <returns></returns>
        private async Task<Dictionary<string, string>> CalculateThicknessAlgorithm(string detectionType, List<double> data)
        {
            double temp = 0;//临时变量
            int findValidValueCount = 0;
            List<double> tempList = new List<double>();
            List<double> finalList = new List<double>();
            Dictionary<string, string> result = new Dictionary<string, string>();
            foreach (var item in data)
            {
                if (item == -2147.483648)
                {
                    findValidValueCount++;
                    if (findValidValueCount >= 10)
                    {
                        if (item != temp)
                        {
                            tempList.Add(item);
                            temp = item;
                            findValidValueCount = 0;
                        }
                    }
                }
                else
                {
                    if (item != temp && item != -2147.483648)
                    {
                        tempList.Add(item);
                        temp = item;
                        findValidValueCount = 0;
                    }
                }
            }
            int index = tempList.IndexOf(-2147.483648);
            int endIndex = 0;
            DateTime starttime = DateTime.Now;
            DateTime endtime = DateTime.Now;
            double timediff = 0;
            ArithmeticMH arithmeticIns = GetArithmeticModel(arithmetic_MH);
            while (index != -1)
            {
                index = tempList.IndexOf(-2147.483648);
                if (index != -1)//找到起始位置
                {
                    endIndex = tempList.IndexOf(-2147.483648, index + 1);
                    if (endIndex != -1)//找到结束位置
                    {
                        double thicknessValue = 0;

                        double[] fList = tempList.GetRange(index + 1, endIndex - index - 1).ToArray();

                        if (arithmeticIns == ArithmeticMH.Avg)
                        {
                            int indexMiddle = fList.Length / 2;
                            if (fList.Length - indexMiddle > 10)
                            {
                                int rangeStart = indexMiddle - 5;
                                thicknessValue = fList.ToList().GetRange(rangeStart, 10).ToArray().Average();//做均值计算
                            }
                            else
                            {
                                thicknessValue = fList[fList.Length / 2];
                            }
                        }
                        else if (arithmeticIns == ArithmeticMH.Min)
                        {
                            thicknessValue = fList.Min();
                        }

                        finalList.Add(thicknessValue);
                        tempList.RemoveAt(index);
                    }
                    else
                    {
                        index = -1;
                    }
                }
                endtime = DateTime.Now;
                timediff = (endtime - starttime).TotalSeconds;
                if (timediff > timeoutValue/*50*/)
                {
                    break;
                }
                if (finalList.Count >= 48)
                {
                    break;
                }
            }
            AddLogEventHandler?.Invoke($"膜厚数据大小：{finalList.Count}");
            if (finalList.Count >= 27 && finalList.Count <= 70)
            {
                int[] indexvalue = new int[] { };
                if (finalList.Count >= 45)
                {
                    indexvalue = new int[] { 5, 6, 7, 24, 25, 26, 43, 44 };//需要获取的膜厚位置，意思第几个波
                    AddLogEventHandler?.Invoke($"膜厚数据取到第44个波");
                }
                else
                {
                    indexvalue = new int[] { 4, 5, 6, 7, 24, 25, 26, 27 };
                    AddLogEventHandler?.Invoke($"膜厚数据取到第27个波");
                }
                AddLogEventHandler?.Invoke($"膜厚数据大于20个");
                //finalList.RemoveRange(0, 5);
                //AddLogEventHandler?.Invoke($"{detectionType}已移除头部5个数据");
                //finalList.RemoveRange(10, finalList.Count - 11);
                //AddLogEventHandler?.Invoke($"{detectionType}已保留10个数据");
                for (int i = 0; i < indexvalue.Length/*finalList.Count*/; i++)
                {
                    result.Add($"{detectionType}{i + 1}", finalList[indexvalue[i]].ToString("0.000"));
                    AddLogEventHandler?.Invoke($"{detectionType}{i + 1}：" + finalList[indexvalue[i]].ToString("0.000"));
                }
                AddLogEventHandler?.Invoke($"{detectionType}已添加完整膜厚数据");
                return result;
            }
            else
            {
                AddLogEventHandler?.Invoke($"膜厚数据小于20个");
                for (int i = 0; i < 10; i++)
                {
                    //if (finalList.Count <= 0 || finalList == null)
                    //{
                    result.Add($"{detectionType}{i + 1}", "0.000");
                    //}
                    //else
                    //{
                    //    result.Add($"{detectionType}{i + 1}", finalList[i].ToString("0.000"));
                    //    AddLogEventHandler?.Invoke($"{detectionType}{i + 1}", finalList[i].ToString("0.000"));
                    //}
                }
                AddLogEventHandler?.Invoke($"{detectionType}已添加膜厚数据");
                return result;
            }
            //return result;
        }

        #endregion

        ///// <summary>
        ///// 发送线激光结果反馈
        ///// </summary>
        ///// <param name="plc">plc对象</param>
        ///// <param name="channelCode">通道代号</param>
        ///// <param name="lineLaserResult">结果</param>
        //private void SendLineLaserResultFeedback(PLCController plc, string channelCode, bool lineLaserResult)
        //{
        //    if (plc != null)
        //    {
        //        switch (channelCode.ToUpper())
        //        {
        //            case "A":
        //                plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.LineLaserResultA, lineLaserResult == true ? 1 : 2);
        //                break;
        //            case "B":
        //                plc?.WriteInt(SignalAdrSetting.dbOp30_FromPc, SignalAdrSetting.LineLaserResultB, lineLaserResult == true ? 1 : 2);
        //                break;
        //        }
        //    }
        //}

        /// <summary>
        /// 线激光获取数据
        /// </summary>
        /// <param name="plc">plc</param>
        /// <param name="channelCode">通道代号</param>
        /// <param name="channelValue">通道号 1，2</param>
        private async Task<ResultReturn> LineLaserGetData(string channelCode, string channelValue)
        {
            Thread.Sleep(200);
            List<string> receiveList = new();
            string? stepResult;
            AddLogEventHandler?.Invoke(channelCode + $"件线激光数据获取信号发送：GetData,{channelValue}\r\n");
            stepResult = socket.sharedSocketSend($"GetData,{channelValue}\r\n");
            AddLogEventHandler?.Invoke(channelCode + "件线激光数据获取信号接收：" + stepResult + "--长度：" + stepResult.Split('@').Length);
            //检查是否是当前件的数据
            if (stepResult != null && stepResult != "error")
            {
                AddLogEventHandler?.Invoke(channelCode + "件线激光数据获取信号接收的长度" + stepResult.Split('@').Length);
                if (stepResult.Split('@')[0] == $"GetData,{channelValue},OK" && stepResult.EndsWith("\r\n") && stepResult.Split('@').Length == 9)
                {
                    AddLogEventHandler?.Invoke(channelCode + "件线激光数据获结果判断正常");
                    KeyenceDataNew model = LineLaserDataParse(stepResult, channelCode);
                    AddLogEventHandler?.Invoke(channelCode + "件线激光数据获取完成");
                    return MessageInfoUtils.Success(model);
                }
                else if (stepResult.Split('@')[0] == $"GetData,{channelValue},NG" && stepResult.EndsWith("\r\n") && stepResult.Split('@').Length == 9)
                {
                    AddLogEventHandler?.Invoke(channelCode + "件线激光数据获结果判断NG");
                    KeyenceDataNew model = LineLaserDataParse(stepResult, channelCode);
                    AddLogEventHandler?.Invoke(channelCode + "件线激光数据获取完成");
                    return MessageInfoUtils.Success(model);
                }
            }
            else
            {
                AddLogEventHandler?.Invoke(channelCode + "件线激光接收数据失败：" + stepResult);
            }
            return MessageInfoUtils.Fail();
        }

        /// <summary>
        /// 线激光数据解析
        /// </summary>
        /// <param name="dataStr">数据字符</param>
        /// <param name="channelCode">通道代号</param>
        /// <returns></returns>
        private KeyenceDataNew LineLaserDataParse(string dataStr, string channelCode)
        {
            KeyenceDataNew data = new();

            string[] strsplit = dataStr.Split('@');
            if (strsplit.Length > 1)
            {
                for (int i = 0; i < strsplit.Length; i++)
                {
                    if (i == 0)
                    {
                        continue;
                    }
                    //正面波直径
                    else if (i == 1)
                    {
                        int count = 1;
                        string[] result = strsplit[i].Split(',');
                        for (int j = 0; j < result.Length; j++)
                        {
                            if (j == 0 || j == 1)
                            {
                                continue;
                            }
                            //if (count == 6 || count == 24)
                            //{
                            data.centerDistance.Add("FS" + count, result[j]);
                            //}
                            count++;
                        }
                    }
                    else if (i == 2)
                    {
                        //背面波间距
                        int count = 1;
                        string[] result = strsplit[i].Split(',');
                        for (int j = 0; j < result.Length; j++)
                        {
                            if (j == 0 || j == 1)
                            {
                                continue;
                            }
                            //if (count == 6 || count == 24)
                            //{
                            data.backCenterDistance.Add("BS" + count, result[j]);
                            //}
                            count++;
                        }
                    }
                    else if (i == 3)
                    {
                        //正面波直径
                        int count = 1;
                        string[] result = strsplit[i].Split(',');
                        for (int j = 0; j < result.Length; j++)
                        {
                            if (j == 0 || j == 1)
                            {
                                continue;
                            }
                            //if (count == 6 || count == 24)
                            //{
                            data.circleDiameter.Add("FD" + count, result[j]);
                            //}
                            count++;
                        }
                    }
                    else if (i == 4)
                    {
                        //背面波直径
                        int count = 1;
                        string[] result = strsplit[i].Split(',');
                        for (int j = 0; j < result.Length; j++)
                        {
                            if (j == 0 || j == 1)
                            {
                                continue;
                            }
                            //if (count == 6 || count == 24)
                            //{
                            data.backCircleDiameter.Add("BD" + count, result[j]);
                            //}
                            count++;
                        }
                    }
                    else if (i == 5)
                    {
                        string[] result = strsplit[i].Split(',');
                        //data.backCircleDiameter.Add("正面bar到第一个波谷的距离", result[1]);
                        data.backCircleDiameter.Add("FtFS", result[1]);
                    }
                    else if (i == 6)
                    {
                        string[] result = strsplit[i].Split(',');
                        //data.backCircleDiameter.Add("背面bar到第一个波谷的距离", result[1]);
                        data.backCircleDiameter.Add("BtFS", result[1]);
                    }
                    else if (i == 7)
                    {
                        string[] result = strsplit[i].Split(',');
                        //data.backCircleDiameter.Add("正面最后一个波谷到bar的距离", result[1]);
                        data.backCircleDiameter.Add("FtLS", result[1]);
                    }
                    else if (i == 8)
                    {
                        string[] result = strsplit[i].Split(',');
                        //data.backCircleDiameter.Add("背面最后一个波谷到bar的距离", result[1]);
                        data.backCircleDiameter.Add("BtLS", result[1]);
                    }
                }
                //AddLogEventHandler?.Invoke(channelCode + "件正面bar到第一个波谷的距离：" + data.backCircleDiameter["正面bar到第一个波谷的距离"].ToString() + ",背面bar到第一个波谷的距离为：" + data.backCircleDiameter["背面bar到第一个波谷的距离"].ToString() + "，正面最后一个波谷到bar的距离为：" + data.backCircleDiameter["正面最后一个波谷到bar的距离"].ToString() + "，背面最后一个波谷到bar的距离为" + data.backCircleDiameter["背面最后一个波谷到bar的距离"].ToString());
                AddLogEventHandler?.Invoke(channelCode + "件正面bar到第一个波谷的距离：" + data.backCircleDiameter["FtFS"].ToString() + ",背面bar到第一个波谷的距离为：" + data.backCircleDiameter["BtFS"].ToString() + "，正面最后一个波谷到bar的距离为：" + data.backCircleDiameter["FtLS"].ToString() + "，背面最后一个波谷到bar的距离为" + data.backCircleDiameter["BtLS"].ToString());
            }
            return data;
        }

        /// <summary>
        /// 遍历公差带
        /// </summary>
        /// <param name="item"></param>
        /// <param name="indicatorToleranceZonesList">公差带配置JSON</param>
        /// <returns></returns>
        private bool ForeachIndicatorToleranceZone(KeyenceDataNew item, IEnumerable<IndicatorToleranceZoneModel> indicatorToleranceZonesList)
        {
            bool indicator = true;
            bool isEnabled = ConfigurationManager.AppSettings["enabled3D"].ToString().ToLower() == "true" ? true : false;
            if (isEnabled)
            {
                foreach (var circle in item.circleDiameter)
                {
                    var indicatorInfo = indicatorToleranceZonesList.FirstOrDefault(p => p.Content.Contains(circle.Key.Substring(0, 2)));
                    var result = JudgeIndicatorToleranceZone(circle.Value, indicatorInfo);
                    if (result == false)
                    {
                        indicator = result;
                        break;
                    }
                }
                foreach (var center in item.centerDistance)
                {
                    if (!indicator)
                    {
                        break;
                    }
                    var indicatorInfo = indicatorToleranceZonesList.FirstOrDefault(p => p.Content.Contains(center.Key.Substring(0, 2)));
                    var result = JudgeIndicatorToleranceZone(center.Value, indicatorInfo);
                    if (result == false)
                    {
                        indicator = result;
                    }
                }
                foreach (var backCircle in item.backCircleDiameter)
                {
                    if (!indicator)
                    {
                        break;
                    }
                    if (backCircle.Key != "FtFS" && backCircle.Key != "FtLS" && backCircle.Key != "BtFS" && backCircle.Key != "BtLS")
                    {
                        var indicatorInfo = indicatorToleranceZonesList.FirstOrDefault(p => p.Content.Contains(backCircle.Key.Substring(0, 2)));
                        var result = JudgeIndicatorToleranceZone(backCircle.Value, indicatorInfo);
                        if (result == false)
                        {
                            indicator = result;
                        }
                    }
                }
                foreach (var backCenter in item.backCenterDistance)
                {
                    if (!indicator)
                    {
                        break;
                    }
                    var indicatorInfo = indicatorToleranceZonesList.FirstOrDefault(p => p.Content.Contains(backCenter.Key.Substring(0, 2)));
                    var result = JudgeIndicatorToleranceZone(backCenter.Value, indicatorInfo);
                    if (result == false)
                    {
                        indicator = result;
                    }
                }
            }
            //foreach (var backCircle in item.backCircleDiameter)//查首尾波到两端的间距
            //{
            //    if (!indicator)
            //    {
            //        break;
            //    }
            //    var indicatorInfo = indicatorToleranceZonesList.Where(p => p.Content.Contains(backCircle.Key/*.Substring(0, 4)*/)).FirstOrDefault();
            //    var result = JudgeIndicatorToleranceZone(backCircle.Value, indicatorInfo);
            //    if (result == false)
            //    {
            //        indicator = result;
            //    }
            //}

            var ftfsCircleindicatorInfo = indicatorToleranceZonesList.Where(p => p.Content == "FtFS").FirstOrDefault();
            var ftfsValue = item.backCircleDiameter.Where(f => f.Key == "FtFS").FirstOrDefault().Value;
            var resultftfs = JudgeIndicatorToleranceZone(ftfsValue, ftfsCircleindicatorInfo);
            if (resultftfs == false)
            {
                indicator = resultftfs;
            }
            var ftlsCircleindicatorInfo = indicatorToleranceZonesList.Where(p => p.Content == "FtLS").FirstOrDefault();
            var ftlsValue = item.backCircleDiameter.Where(f => f.Key == "FtLS").FirstOrDefault().Value;
            var resultftls = JudgeIndicatorToleranceZone(ftfsValue, ftfsCircleindicatorInfo);
            if (resultftls == false)
            {
                indicator = resultftls;
            }
            var btfsCircleindicatorInfo = indicatorToleranceZonesList.Where(p => p.Content == "BtFS").FirstOrDefault();
            var btfsValue = item.backCircleDiameter.Where(f => f.Key == "BtFS").FirstOrDefault().Value;
            var resultbtfs = JudgeIndicatorToleranceZone(ftfsValue, ftfsCircleindicatorInfo);
            if (resultbtfs == false)
            {
                indicator = resultbtfs;
            }
            var btlsCircleindicatorInfo = indicatorToleranceZonesList.Where(p => p.Content == "BtLS").FirstOrDefault();
            var btlsValue = item.backCircleDiameter.Where(f => f.Key == "BtLS").FirstOrDefault().Value;
            var resultbtls = JudgeIndicatorToleranceZone(ftfsValue, ftfsCircleindicatorInfo);
            if (resultbtls == false)
            {
                indicator = resultbtls;
            }
            return indicator;
        }

        /// <summary>
        /// 判断是否在公差带范围内
        /// </summary>
        /// <param name="values">基准值</param>
        /// <param name="indicatorToleranceZones">公差带</param>
        /// <returns>True表示在公差范围内</returns>
        private bool JudgeIndicatorToleranceZone(string values, IndicatorToleranceZoneModel indicatorToleranceZones)
        {
            bool indicator = true;
            if (string.IsNullOrEmpty(values) || indicatorToleranceZones == null)
            {
                //return indicator;
                return false;
            }
            float? DetectedData = float.Parse(values);
            if (indicatorToleranceZones.ContentType == "0") //正负范围
            {
                if ((indicatorToleranceZones.Indicator + indicatorToleranceZones.ToleranceZone) < DetectedData
                    || (indicatorToleranceZones.Indicator - indicatorToleranceZones.ToleranceZone) > DetectedData)
                {
                    indicator = false;
                }
            }
            else if (indicatorToleranceZones.ContentType == "1") //最大值
            {
                if (indicatorToleranceZones.ToleranceZone + indicatorToleranceZones.Indicator < DetectedData)
                {
                    indicator = false;
                }
            }
            else if (indicatorToleranceZones.ContentType == "2") //最小值
            {
                if (indicatorToleranceZones.Indicator - indicatorToleranceZones.ToleranceZone > DetectedData)
                {
                    indicator = false;
                }
            }

            return indicator;
        }

        /// <summary>
        /// 判断膜厚是否在公差带范围内
        /// </summary>
        /// <param name="values">基准值</param>
        /// <param name="indicatorToleranceZones">公差带</param>
        /// <returns>True表示在公差范围内</returns>
        private async Task<bool> JudgeThicknessIndicatorToleranceZone(string values, IndicatorToleranceZoneModel indicatorToleranceZones)
        {
            bool indicator = true;
            if (string.IsNullOrEmpty(values) || indicatorToleranceZones == null)
            {
                //return indicator;
                return false;
            }
            double? DetectedData = double.Parse(values);
            if (indicatorToleranceZones.ContentType == "0") //正负范围
            {
                if ((indicatorToleranceZones.Indicator + indicatorToleranceZones.ToleranceZone) < DetectedData
                    || (indicatorToleranceZones.Indicator - indicatorToleranceZones.ToleranceZone) > DetectedData)
                {
                    indicator = false;
                }
            }
            else if (indicatorToleranceZones.ContentType == "1") //最大值
            {
                if (indicatorToleranceZones.ToleranceZone + indicatorToleranceZones.Indicator < DetectedData)
                {
                    indicator = false;
                }
            }
            else if (indicatorToleranceZones.ContentType == "2") //最小值
            {
                if (indicatorToleranceZones.Indicator - indicatorToleranceZones.ToleranceZone > DetectedData)
                {
                    indicator = false;
                }
            }

            return indicator;
        }

        /// <summary>
        /// 遍历膜厚公差带
        /// </summary>
        /// <param name="item"></param>
        /// <param name="indicatorToleranceZonesList">公差带配置JSON</param>
        /// <returns></returns>
        private async Task<bool> ForeachThicknessIndicatorToleranceZone(string channelCode, IEnumerable<IndicatorToleranceZoneModel> indicatorToleranceZonesList)
        {
            bool indicator = true;
            if (channelCode.ToUpper() == "A")
            {
                foreach (var item in DataShift.FrontThicknessA)
                {
                    var indicatorInfo = indicatorToleranceZonesList.FirstOrDefault(p => p.Content.Contains(item.Key.Substring(0, 3)));
                    var result = await JudgeThicknessIndicatorToleranceZone(item.Value, indicatorInfo);
                    if (result == false)
                    {
                        indicator = result;
                        break;
                    }
                }
                foreach (var item in DataShift.BackThicknessA)
                {
                    var indicatorInfo = indicatorToleranceZonesList.FirstOrDefault(p => p.Content.Contains(item.Key.Substring(0, 3)));
                    var result = await JudgeThicknessIndicatorToleranceZone(item.Value, indicatorInfo);
                    if (result == false)
                    {
                        indicator = result;
                        break;
                    }
                }
            }
            else if (channelCode.ToUpper() == "B")
            {
                foreach (var item in DataShift.FrontThicknessB)
                {
                    var indicatorInfo = indicatorToleranceZonesList.FirstOrDefault(p => p.Content.Contains(item.Key.Substring(0, 3)));
                    var result = await JudgeThicknessIndicatorToleranceZone(item.Value, indicatorInfo);
                    if (result == false)
                    {
                        indicator = result;
                        break;
                    }
                }
                foreach (var item in DataShift.BackThicknessB)
                {
                    var indicatorInfo = indicatorToleranceZonesList.FirstOrDefault(p => p.Content.Contains(item.Key.Substring(0, 3)));
                    var result = await JudgeThicknessIndicatorToleranceZone(item.Value, indicatorInfo);
                    if (result == false)
                    {
                        indicator = result;
                        break;
                    }
                }
            }

            return indicator;
        }
    }

    /// <summary>
    /// 线扫设备状态
    /// </summary>
    public class LineLaserDeviceStatus
    {
        /// <summary>
        /// 线扫1状态
        /// </summary>
        public bool? LineLaser1DeviceStatus { get; set; }

        public bool? LineLaser2DeviceStatus { get; set; }
        public bool? LineLaser3DeviceStatus { get; set; }
        public bool? LineLaser4DeviceStatus { get; set; }
    }

    public enum ArithmeticMH
    {
        Avg = 1,
        Min = 2
    }

    /// <summary>
    /// 膜厚原数据
    /// </summary>
    public class SourceData
    {
        /// <summary>
        /// 脉冲
        /// </summary>
        public int PulseCount { get; set; }

        /// <summary>
        /// 距离
        /// </summary>
        public double Distance { get; set; }

        /// <summary>
        /// 膜厚
        /// </summary>
        public double Thickness { get; set; }
    }
}